Típusok
A típusérték olyan érték, amely más értékeket sorol be . A típus szerint besorolt értéknek az adott típusnak kell megfelelnie . Az M típusú rendszer a következő típusokból áll:
Primitív típusok, amelyek primitív értékeket osztályoznak (
binary
,date
,datetime
,datetimezone
,duration
list
,logical
null
number
record
, ,text
, ),time
),type
és számos absztrakt típust is tartalmaznak (function
,table
, ,any
és )anynonnull
none
Rekordtípusok, amelyek mezőnevek és értéktípusok alapján osztályozzák a rekordértékeket
Listatípusok, amelyek egyetlen elem alaptípusával osztályozzák a listákat
Függvénytípusok, amelyek a paraméterek típusai alapján osztályozzák a függvényértékeket, és visszaadják az értékeket
Táblázattípusok, amelyek oszlopnevek, oszloptípusok és kulcsok alapján sorolják be a táblaértékeket
Null értékű típusok, amelyek a null értéket az alaptípus szerint besorolt összes érték mellett osztályozzák
Típustípusok, amelyek a típusokat osztályozzák
A primitív típusok készlete tartalmazza a primitív értékek típusait és számos absztrakt típust, amelyek olyan típusok, amelyek egyedileg nem sorolnak be értékeket: function
, table
, any
anynonnull
és none
. Minden függvényérték megfelel az absztrakt típusnakfunction
, az összes táblaértéknek az absztrakt típushoztable
, az absztrakt típushoz tartozó összes értéknek, az absztrakt típusnak any
anynonnull
nem null értékű értékeknek, az absztrakt típusnak none
pedig nincs értéke. A típuskifejezésnek none
hibát kell okoznia, vagy nem lehet leállni, mivel nem hozható létre olyan érték, amely megfelel a típusnak none
. Vegye figyelembe, hogy a primitív típusok function
table
absztraktak, mivel egyetlen függvény vagy tábla sem közvetlenül ezekből a típusokból áll. A primitív típusok record
nem list
absztraktak, mert egy definiált mezők nélküli nyitott rekordot, illetve egy tetszőleges típusú listát jelölnek.
Minden olyan típust, amely nem tagja a primitív típusok zárt készletének, valamint null értékű megfelelőiknek, együttesen egyéni típusoknak nevezzük. Az egyéni típusok a következővel type-expression
írhatók:
type-expression:
elsődleges kifejezés
type
elsődleges típus
type:
elsődleges kifejezés
elsődleges típus
elsődleges típus:
primitív típusú
rekordtípus
listatípus
függvénytípus
táblatípus
nullable-type
primitív típusú: az egyik
any anynonnull binary date datetime datetimezone duration function list logical
none null number record table text time type
A primitív típusú nevek olyan környezetfüggő kulcsszavak, amelyeket csak típuskörnyezetben ismernek fel. A zárójelek használata egy típuskörnyezetben visszaállítja a nyelvtant egy reguláris kifejezési környezetbe, és a típus kulcsszó használatával vissza kell lépnie egy típuskörnyezetbe. Egy függvény típuskörnyezetben való meghívásához például zárójelek használhatók:
type nullable ( Type.ForList({type number}) )
// type nullable {number}
Zárójelek is használhatók olyan változók elérésére, amelyek neve egy primitív típusú névvel ütközik:
let record = type [ A = any ] in type {(record)}
// type {[ A = any ]}
Az alábbi példa egy számlistát osztályozó típust határoz meg:
type { number }
Hasonlóképpen, az alábbi példa egy egyéni típust határoz meg, amely a rekordokat kötelezően elnevezett X
mezőkkel sorolja be, és Y
amelyek értékei számok:
type [ X = number, Y = number ]
Az érték írott típusa a standard kódtárfüggvény Value.Typehasználatával érhető el, ahogyan az alábbi példákban is látható:
Value.Type( 2 ) // type number
Value.Type( {2} ) // type list
Value.Type( [ X = 1, Y = 2 ] ) // type record
Az is
operátor annak meghatározására szolgál, hogy egy érték típusa kompatibilis-e egy adott típussal, ahogy az alábbi példákban is látható:
1 is number // true
1 is text // false
{2} is list // true
Az as
operátor ellenőrzi, hogy az érték kompatibilis-e az adott típussal, és hibát jelez, ha nem. Ellenkező esetben az eredeti értéket adja vissza.
Value.Type( 1 as number ) // type number
{2} as text // error, type mismatch
Vegye figyelembe, hogy az és is
az as
operátorok csak a null értékű primitív típusokat fogadják el a megfelelő operandusként. Az M nem biztosít olyan értékeket, amelyek az egyéni típusoknak való megfelelést ellenőrzik.
A típus X
akkor és csak akkor kompatibilis egy típussal Y
, ha az összes, a megfelelő X
értéknek is megfelel Y
. Minden típus kompatibilis a típussal any
, és egyetlen típus sem (de none
önmagában) nem kompatibilis a típussal none
. Az alábbi grafikon a kompatibilitási kapcsolatot mutatja be. (A típuskompatibilitás reflexív és tranzitív. Ez egy rácsot képez, amelynek felső része a típusany
, az alsó érték pedig a típusnone
.) Az absztrakt típusok neve dőlt betűvel van beállítva.
Típusértékekhez a következő operátorok vannak definiálva:
Operátor | Eredmény |
---|---|
x = y |
Equal |
x <> y |
Nem egyenlő |
x ?? y |
Coalesce |
A típusértékek natív típusa a belső típus type
.
Az M nyelv típusai egy különálló hierarchiát alkotnak, amely a típusnál any
gyökerezik, és ez az a típus, amely az összes értéket osztályozza. Minden M érték pontosan egy primitív altípusnak any
felel meg. A típusból any
származó primitív típusok zárt készlete a következő:
-
type null
, amely a null értéket osztályozza. -
type logical
, amely igaz és hamis értékeket sorol be. -
type number
, amely számértékeket sorol be. -
type time
, amely az időértékeket sorolja be. -
type date
, amely dátumértékeket sorol be. -
type datetime
, amely dátum/idő értékeket sorol be. -
type datetimezone
, amely a datetimezone értékeket sorolja be. -
type duration
, amely az időtartamértékeket sorolja be. -
type text
, amely a szöveges értékeket sorolja be. -
type binary
, amely bináris értékeket sorol be. -
type type
, amely típusértékeket sorol be. -
type list
, amely a listaértékeket sorolja be. -
type record
, amely a rekordértékeket osztályozza. -
type table
, amely a táblaértékeket sorolja be. -
type function
, amely a függvényértékeket sorolja be. -
type anynonnull
, amely a null értéket nem tartalmazó összes értéket osztályozza. -
type none
, amely nem sorol be értékeket.
A típus any
absztrakció, az összes értéket az M osztályozza, az M-ben pedig az összes típus kompatibilis.any
A típusváltozók any
az összes lehetséges értékhez köthetők. Mivel any
absztrakció, ezért nem írható értékekhez , vagyis egyetlen érték sem lehet közvetlenül típus.any
A lista bármely értéke megfelel a belső típusnak list
, amely nem korlátozza a listaértéken belüli elemeket.
listatípus:
{
elemtípus}
elemtípus:
típus
A listatípus kiértékelésének eredménye egy listatípus értéke, amelynek alaptípusa .list
Az alábbi példák a homogén listatípusok deklarálásának szintaxisát szemléltetik:
type { number } // list of numbers type
{ record } // list of records type
{{ text }} // list of lists of text values
Az érték akkor felel meg egy listatípusnak, ha az érték lista, és a listaérték minden eleme megfelel a listatípus elemtípusának.
A listatípus elemtípusa egy kötött elemet jelöl: a megfelelő lista összes eleme megfelel az elemtípusnak.
Minden olyan érték, amely egy rekord, megfelel a belső típusú rekordnak, amely nem korlátozza a mezőneveket vagy az értékeket egy rekordértéken belül. A rekord típusú értékekkel korlátozható az érvényes nevek halmaza, valamint az ezekhez a nevekhez társítható értékek típusai.
rekordtípus:
[
open-record-marker]
[
mező-specifikáció-listaopt]
[
field-specification-list , open-record-marker]
mezőspecifikációs lista:
mezős specifikáció
mezőspecifikáció,
mezőspecifikációs listája
mezős specifikáció:
optional
opt field-name field-type-specificationopt
mezőtípus-specifikáció:
=
mezőtípus
mezőtípus:
típus
open-record-marker:
...
A rekordtípus kiértékelésének eredménye egy olyan típusérték, amelynek alaptípusa .record
Az alábbi példák a rekordtípusok deklarálásának szintaxisát szemléltetik:
type [ X = number, Y = number]
type [ Name = text, Age = number ]
type [ Title = text, optional Description = text ]
type [ Name = text, ... ]
A rekordtípusok alapértelmezés szerint bezárva vannak, ami azt jelenti, hogy a mezőkpecifikációs listában nem szereplő további mezők nem lehetnek megfelelő értékekben. Az openrecord-marker rekordtípusba való belevétele azt jelzi, hogy a típus nyitott, ami lehetővé teszi a mezőspecifikációs listában nem szereplő mezőket. A következő két kifejezés egyenértékű:
type record // primitive type classifying all records
type [ ... ] // custom type classifying all records
Az érték akkor felel meg egy rekordtípusnak, ha az érték egy rekord, és a rekordtípus minden mezős specifikációja teljesül. A mezőspecifikáció teljesül, ha az alábbiak bármelyike igaz:
A specifikáció azonosítójának megfelelő mezőnév szerepel a rekordban, és a társított érték megfelel a specifikáció típusának
A specifikáció nem kötelezőként van megjelölve, és nem található megfelelő mezőnév a rekordban
A megfelelő érték tartalmazhat olyan mezőneveket, amelyek nem szerepelnek a mezőspecifikációs listában, ha és csak akkor, ha a rekordtípus nyitva van.
A függvényértékek megfelelnek a primitív típusnak function
, amely nem korlátozza a függvény formális paramétereinek típusait vagy a függvény visszatérési értékét. Az egyéni függvény típusú értékekkel típuskorlátozások helyezhetőek el a megfelelő függvényértékek aláírásán.
függvénytípus:
function (
parameter-specification-listopt)
function-return-type
parameter-specification-list:
required-parameter-specification-list
required-parameter-specification-list,
optional-parameter-specification-list
optional-parameter-specification-list
required-parameter-specification-list:
required-parameter-specification
required-parameter-specification,
required-parameter-specification-list
required-parameter-specification:
paraméter-specifikáció
optional-parameter-specification-list:
optional-parameter-specification
optional-parameter-specification,
optional-parameter-specification-list
optional-parameter-specification:
optional
paraméter-specifikáció
paraméter-specifikáció:
paraméternév paramétertípusa
függvény-return-type:
követelés
állítás:
as
nullable-primitive-type
A függvénytípus kiértékelésének eredménye egy olyan típusérték, amelynek alaptípusa .function
Az alábbi példák a függvénytípusok deklarálásának szintaxisát szemléltetik:
type function (x as text) as number
type function (y as number, optional z as text) as any
A függvényérték akkor felel meg egy függvénytípusnak, ha a függvényérték visszatérési típusa kompatibilis a függvénytípus visszatérési típusával, és a függvénytípus minden paraméter-specifikációja kompatibilis a függvény helyhez kötött formális paraméterével. A paraméterspecifikáció kompatibilis a formális paraméterrel, ha a megadott paramétertípus kompatibilis a formális paraméter típusával, és a paraméter specifikációja nem kötelező, ha a formális paraméter nem kötelező.
A függvénytípus-megfelelőség meghatározásához a rendszer figyelmen kívül hagyja a formális paraméterneveket.
A paraméter opcionálisként való megadása implicit módon null értékűvé teszi a paraméter típusát. A következő azonos függvénytípusok hozhatók létre:
type function (optional x as text) as any
type function (optional x as nullable text) as any
A tábla típusú értékek a táblaértékek szerkezetének meghatározására szolgálnak.
táblatípus:
table
sortípus
sortípus:
[
mező-specifikáció-listaopt]
A táblatípus kiértékelésének eredménye egy olyan típusérték, amelynek alaptípusa .table
A tábla sortípusa a tábla oszlopneveit és oszloptípusait zárt rekordtípusként határozza meg. Annak érdekében, hogy az összes táblaérték megfeleljen a típusnak table
, a sor típusa típus record
(az üres nyitott rekordtípus). A típustábla tehát absztrakció, mivel egyetlen táblaérték sem rendelkezhet table
sortípussal (de minden táblaértéknek van egy sortípusa, amely kompatibilis a típus table
sortípusával). Az alábbi példa egy táblatípus felépítését mutatja be:
type table [A = text, B = number, C = binary]
// a table type with three columns named A, B, and C
// of column types text, number, and binary, respectively
A tábla típusú értékek a táblaérték kulcsainak definícióját is tartalmazzák. A kulcs oszlopnevek halmaza. Legfeljebb egy kulcs jelölhető ki a tábla elsődleges kulcsaként. (Az M-ben a táblakulcsoknak nincs szemantikai jelentése. A külső adatforrások, például adatbázisok vagy OData-hírcsatornák esetében azonban gyakori, hogy kulcsokat határoznak meg a táblákon. A Power Query kulcsadatokkal javítja a fejlett funkciók teljesítményét, például a forrásközi illesztési műveleteket.)
A standard kódtár függvények Type.TableKeys
, Type.AddTableKey
és Type.ReplaceTableKeys
egy táblatípus kulcsainak lekérésére használhatók, hozzáadnak egy kulcsot egy táblázattípushoz, és lecserélik a táblatípus összes kulcsát.
Type.AddTableKey(tableType, {"A", "B"}, false)
// add a non-primary key that combines values from columns A and B
Type.ReplaceTableKeys(tableType, {})
// returns type value with all keys removed
A null értékű változatok bármelyike type T
null értékű típussal származtatható:
nullable-type:
nullable
típus
Az eredmény egy absztrakt típus, amely lehetővé teszi a T vagy az érték null
típusú értékeket.
42 is nullable number // true null is
nullable number // true
A T leírója type nullable
a T vagy a Ttype
csökken. (Ne feledje, hogy a null értékű típusok absztraktak, és egyetlen érték sem lehet közvetlenül absztrakt típusú.)
Value.Type(42 as nullable number) // type number
Value.Type(null as nullable number) // type null
A standard kódtárfüggvények Type.IsNullable
Type.NonNullable
használatával tesztelhető egy típus a nullhihetőség szempontjából, és eltávolítható a típusból.
Az alábbi visszatartás (bármely type T
):
-
type T
kompatibilis atype nullable T
-
Type.NonNullable(type T)
kompatibilis atype T
A következők párban egyenértékűek (bármely type T
):
type nullable any
any
Type.NonNullable(type any)
type anynonnull
type nullable none
type null
Type.NonNullable(type null)
type none
type nullable nullable T
type nullable T
Type.NonNullable(Type.NonNullable(type T))
Type.NonNullable(type T)
Type.NonNullable(type nullable T)
Type.NonNullable(type T)
type nullable (Type.NonNullable(type T))
type nullable T
Az érték írásvédett típusa az a típus, amelynek egy értéknek megfelelőnek van deklarálva .
Az érték a kódtárfüggvény Value.ReplaceType
használatával írható le. Ez a függvény egy új értéket ad vissza a megadott típussal, vagy hibát jelez, ha az új típus nem kompatibilis az értékkel.
Ha egy érték típushoz van írva, csak korlátozott megfelelőségi ellenőrzés történik:
- A leírandó típusnak nem absztraktnak, nem null értékűnek kell lennie, és kompatibilisnek kell lennie az érték belső (natív) primitív típusával.
- Ha egy struktúrát meghatározó egyéni típust írnak le, annak meg kell egyeznie az érték szerkezetével.
- Rekordok esetében: A típusnak be kell zárnia, meg kell határoznia az értékével megegyező számú mezőt, és nem tartalmazhat opcionális mezőket. (A típus mezőnevei és mezőtípusai lecserélik a rekordhoz jelenleg társítottakat. A meglévő mezőértékek azonban nem lesznek ellenőrizve az új mezőtípusokon.)
- Táblák esetén: A típusnak ugyanannyi oszlopot kell meghatároznia, mint az értéknek. (A típus oszlopnevei és oszloptípusai lecserélik a táblához jelenleg társítottakat. A meglévő oszlopértékek azonban nem lesznek ellenőrizve az új oszloptípusokon.)
- Függvények esetén: A típusnak ugyanazt a számú kötelező paramétert, valamint az opcionális paraméterek számát kell meghatároznia, mint az érték. (A típus paramétere és visszatérési helyességei, valamint paraméternevei lecserélik a függvényérték aktuális típusához társítottakat. Az új állítások azonban nem befolyásolják a függvény tényleges viselkedését.)
- Listák esetén: Az értéknek listának kell lennie. (A meglévő listaelemek azonban nem lesznek bejelölve az új elemtípussal.)
A kódtárfüggvények dönthetnek úgy, hogy összetett típusokat számítanak ki és írnak le az eredményekhez a bemeneti értékek lejegyezett típusai alapján.
Az érték írott típusa a kódtárfüggvény Value.Type
használatával kérhető le. Példa:
Value.Type( Value.ReplaceType( {1}, type {number} )
// type {number}
A típusegyenlítés nincs definiálva az M-ben. Az M-implementáció opcionálisan dönthet úgy, hogy saját szabályait használja a típusértékek közötti egyenlőség összehasonlítására. Az egyenlőség két típusértékének összehasonlítása akkor értékelhető ki true
, ha a végrehajtás azonosnak tekinti őket, és false
egyébként. Mindkét esetben a visszaadott válasznak konzisztensnek kell lennie, ha ugyanazt a két értéket ismételten összehasonlítják. Vegye figyelembe, hogy egy adott implementációban bizonyos azonos típusú értékek (például (type text) = (type text)
) összehasonlítása visszaállhat true
, míg mások (például (type [a = text]) = (type [a = text])
) összehasonlítása nem feltétlenül lehetséges.
Egy adott típus és a null értékű primitív típus közötti kompatibilitás a kódtárfüggvény Type.Is
használatával határozható meg, amely elsőként egy tetszőleges típusértéket fogad el, második argumentumaként pedig null értékű primitív típusértéket:
Type.Is(type text, type nullable text) // true
Type.Is(type nullable text, type text) // false
Type.Is(type number, type text) // false
Type.Is(type [a=any], type record) // true
Type.Is(type [a=any], type list) // false
Az M nem támogatja egy adott típus és egy egyéni típus kompatibilitásának meghatározását.
A standard kódtár tartalmaz egy függvénygyűjteményt, amely kinyeri a meghatározó jellemzőket egy egyéni típusból, így az egyes kompatibilitási tesztek M-kifejezésként implementálhatók. Az alábbiakban néhány példa látható; részletes információkért tekintse meg az M kódtár specifikációját.
Type.ListItem( type {number} )
// type number
Type.NonNullable( type nullable text )
// type text
Type.RecordFields( type [A=text, B=time] )
// [ A = [Type = type text, Optional = false],
// B = [Type = type time, Optional = false] ]
Type.TableRow( type table [X=number, Y=date] )
// type [X = number, Y = date]
Type.FunctionParameters(
type function (x as number, optional y as text) as number)
// [ x = type number, y = type nullable text ]
Type.FunctionRequiredParameters(
type function (x as number, optional y as text) as number)
// 1
Type.FunctionReturn(
type function (x as number, optional y as text) as number)
// type number