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, durationlist, numberlogicalrecordnull, , text, ), time), typeés számos absztrakt típust is tartalmaznak (function, table, , anyés ) anynonnullnone

  • 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, anyanynonnull é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 anyanynonnullnem null értékű értékeknek, az absztrakt típusnak nonepedig 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 functiontable 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

      typeelső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 ]

Egy érték írott típusa az Érték.Típus standard kódtárfüggvény használatával érhető el, ahogyan az alábbi példákban 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 as az is 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 Xakkor é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ípuskompatibilitás

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.

Primitív típusok

Az M nyelv típusai egy különálló hierarchiát alkotnak, amely a típusnál anygyökerezik, és ez az a típus, amely az összes értéket osztályozza. Minden M érték pontosan egy primitív altípusnak anyfelel 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.

Bármilyen típus

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

Listatípusok

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.

Bejegyzéstípusok

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ó:

      optionalopt 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.

Függvénytípusok

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:

      optionalparaméter-specifikáció
paraméter-specifikáció:
      paraméternév paramétertípusa
függvény-return-type:
      követelés
Állítás:

      asnullable-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

Táblázattípusok

A tábla típusú értékek a táblaértékek szerkezetének meghatározására szolgálnak.

táblatípus:
      tablesortí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 tablesortípussal (de minden táblaértéknek van egy sortípusa, amely kompatibilis a típus tablesortí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

Null értékű típusok

A null értékű változatok bármelyike type Tnull értékű típussal származtatható:

nullable-type:
      nullabletype

Az eredmény egy absztrakt típus, amely lehetővé teszi a T vagy az érték nulltípusú értékeket.

42 is nullable number             // true null is
nullable number                   // true

A T leírója type nullablea T vagy a T indexre type nulltypecsö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.IsNullableType.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 a type nullable T
  • Type.NonNullable(type T) kompatibilis a type 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

Egy érték írott típusa

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.ReplaceTypehaszná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.Typehasználatával kérhető le. Példa:

Value.Type( Value.ReplaceType( {1}, type {number} ) 
// type {number}

Típusegyenlítés és kompatibilitás

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.Ishaszná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