Sdílet prostřednictvím


Typy

Hodnota typu je hodnota, která klasifikuje jiné hodnoty. Hodnota klasifikovaná typem je označena tak, aby odpovídala danému typu. Systém typů M se skládá z následujících typů typů:

  • Primitivní typy, které klasifikují primitivní hodnoty (binary, , , datetimedatetimezone, durationlist, logical, , numbernull, record, text, typetime) a zahrnují také řadu abstraktních typů (function, table, anyanynonnull a none) date

  • Typy záznamů, které klasifikují hodnoty záznamů na základě názvů polí a typů hodnot

  • Typy seznamů, které klasifikují seznamy pomocí jednoho základního typu položky

  • Typy funkcí, které klasifikují hodnoty funkcí na základě typů jejich parametrů a návratových hodnot

  • Typy tabulek, které klasifikují hodnoty tabulky na základě názvů sloupců, typů sloupců a klíčů

  • Typy s možnou hodnotou null, které kromě všech hodnot klasifikovaných základním typem klasifikují hodnotu null.

  • Typy typů, které klasifikují hodnoty, které jsou typy

Sada primitivních typů zahrnuje typy primitivních hodnot a řadu abstraktních typů, které jsou typy, které jednoznačně klasifikují žádné hodnoty: function, table, anyanynonnull a none. Všechny hodnoty funkce odpovídají abstraktnímu typu function, všechny hodnoty tabulky abstraktnímu typu table, všechny hodnoty abstraktního typu any, všechny nenulové hodnoty abstraktního typu anynonnulla žádné hodnoty abstraktního typu none. Výraz typu none musí vyvolat chybu nebo nelze ukončit, protože nelze vytvořit žádnou hodnotu, která odpovídá typu none. Mějte na paměti, že primitivní typy function a table jsou abstraktní, protože žádná funkce nebo tabulka nejsou přímo z těchto typů. Primitivní typy record a list nejsou abstraktní, protože představují otevřený záznam bez definovaných polí a seznam typů.

Všechny typy, které nejsou členy uzavřené sady primitivních typů a jejich protějšky s možnou hodnotou null, se souhrnně označují jako vlastní typy. Vlastní typy lze zapsat pomocí type-expression:

type-expression:
      primary-expression

      typeprimární typ
type:
      primary-expression
      primární typ
primární typ:
      primitivní typ
      typ záznamu
      list-type
      function-type
      table-type
      nullable-type
primitivní typ:
jeden z
      any anynonnull binary date datetime datetimezone duration function list logical
      none null number record table text time type

Názvy primitivních typů jsou kontextová klíčová slova rozpoznaná pouze v kontextu typu . Použití závorek v kontextu typu přesune gramatiku zpět do kontextu regulárního výrazu, což vyžaduje použití klíčového slova typu k návratu do kontextu typu. Například k vyvolání funkce v kontextu typu lze použít závorky:

type nullable ( Type.ForList({type number}) )   
// type nullable {number}

Závorky lze použít také pro přístup k proměnné, jejíž název koliduje s primitivním názvem typu :

let  record = type [ A = any ]  in  type {(record)} 
// type {[ A = any ]}

Následující příklad definuje typ, který klasifikuje seznam čísel:

type { number }

Podobně následující příklad definuje vlastní typ, který klasifikuje záznamy s povinnými poli pojmenovanými X a Y jejichž hodnoty jsou čísla:

type [ X = number, Y = number ]

Přiřazený typ hodnoty se získá pomocí standardní funkce knihovny Value.Type, jak je znázorněno v následujících příkladech:

Value.Type( 2 )                 // type number 
Value.Type( {2} )               // type list 
Value.Type( [ X = 1, Y = 2 ] )  // type record

Operátor is slouží k určení, jestli je typ hodnoty kompatibilní s daným typem, jak je znázorněno v následujících příkladech:

1 is number          // true 
1 is text            // false 
{2} is list          // true

Operátor as zkontroluje, jestli je hodnota kompatibilní s daným typem, a pokud není, vyvolá chybu. V opačném případě vrátí původní hodnotu.

Value.Type( 1 as number )   // type number 
{2} as text                 // error, type mismatch

Všimněte si, že operátory a as operátory is přijímají jako pravý operand pouze primitivní typy s možnou hodnotou null. M neposkytuje prostředky ke kontrole shody hodnot s vlastními typy.

Typ X je kompatibilní s typemY, pokud a pouze pokud všechny hodnoty, které odpovídají X také .Y Všechny typy jsou kompatibilní s typem any a žádné typy (ale none samotné) jsou kompatibilní s typem none. Následující graf ukazuje vztah kompatibility. (Kompatibilita typu je reflexní a tranzitivní. Tvoří mřížku s typem any jako horní a jako none nejnižší hodnotu.) Názvy abstraktních typů jsou nastavené kurzívou.

Kompatibilita typů

Pro hodnoty typu jsou definovány následující operátory:

Operátor Výsledek
x = y Equal
x <> y Not equal
x ?? y Coalesce

Nativní typ hodnot typu je vnitřní typ type.

Primitivní typy

Typy v jazyce M tvoří nesouvislou hierarchii kořene typu any, což je typ, který klasifikuje všechny hodnoty. Jakákoli hodnota jazyka M odpovídá přesně jednomu primitivnímu podtypu any. Uzavřená sada primitivních typů odvozených z typu any je následující:

  • type null, která klasifikuje hodnotu null.
  • type logical, která klasifikuje hodnoty true a false.
  • type number, který klasifikuje číselné hodnoty.
  • type time, který klasifikuje časové hodnoty.
  • type date, který klasifikuje hodnoty kalendářních dat.
  • type datetime, který klasifikuje hodnoty datetime.
  • type datetimezone, který klasifikuje hodnoty datetimezone.
  • type duration, který klasifikuje hodnoty doby trvání.
  • type text, který klasifikuje textové hodnoty.
  • type binary, který klasifikuje binární hodnoty.
  • type type, který klasifikuje hodnoty typu.
  • type list, který klasifikuje hodnoty seznamu.
  • type record, který klasifikuje hodnoty záznamů.
  • type table, která klasifikuje hodnoty tabulky.
  • type function, který klasifikuje hodnoty funkce.
  • type anynonnull, která klasifikuje všechny hodnoty s výjimkou hodnoty null.
  • type none, který klasifikuje žádné hodnoty.

Libovolný typ

Typ any je abstraktní, klasifikuje všechny hodnoty v jazyce M a všechny typy v jazyce M jsou kompatibilní s any. Proměnné typu any mohou být vázány na všechny možné hodnoty. Vzhledem k tomu any , že je abstraktní, nelze ji připsat k hodnotám – to znamená, že žádná hodnota není přímo typu any.

Typy seznamů

Jakákoli hodnota, která je seznamem, odpovídá vnitřnímu typu list, který neukládá žádná omezení pro položky v hodnotě seznamu.

typ seznamu:
      { item-type }
item-type:
      typ

Výsledkem vyhodnocení typu seznamu je hodnota typu seznamu, jejíž základní typ je list.

Následující příklady ilustrují syntaxi pro deklarování homogenních typů seznamů:

type { number }        // list of numbers type 
     { record }        // list of records type
     {{ text }}        // list of lists of text values

Hodnota odpovídá typu seznamu, pokud je hodnota seznamem a každá položka v této hodnotě seznamu odpovídá typu položky typu seznamu.

Typ položky typu seznamu označuje vazbu: všechny položky odpovídajícího seznamu odpovídají typu položky.

Typy záznamů

Jakákoli hodnota, která je záznamem, odpovídá vnitřnímu záznamu typu, který neukládá žádná omezení názvů polí nebo hodnot v hodnotě záznamu. Hodnota typu záznamu slouží k omezení sady platných názvů a typů hodnot, které mají být k těmto názvům přidruženy.

typ záznamu:
      [open-record-marker ]
      [ field-specification-listopt ]
      [ field-specification-list , open-record-marker ]
field-specification-list:
      specifikace pole
      field-specification , field-specification-list
specifikace pole:

      optionalopt field-name field-type-specificationopt
specifikace typu pole:

      =typ pole
typ pole:
      type
open-record-marker:

      ...

Výsledkem vyhodnocení typu záznamu je hodnota typu typu, jejíž základní typ je record.

Následující příklady ilustrují syntaxi deklarování typů záznamů:

type [ X = number, Y = number] 
type [ Name = text, Age = number ]
type [ Title = text, optional Description = text ] 
type [ Name = text, ... ]

Typy záznamů jsou ve výchozím nastavení zavřené, což znamená, že další pole, která nejsou v seznamu polí, nesmí být v odpovídajících hodnotách přítomna. Zahrnutí značky openrecord-marker v typu záznamu deklaruje typ, který má být otevřen, což umožňuje pole, která nejsou přítomna v seznamu specifikací polí. Následující dva výrazy jsou ekvivalentní:

type record   // primitive type classifying all records 
type [ ... ]  // custom type classifying all records

Hodnota odpovídá typu záznamu, pokud je hodnota záznamem a každá specifikace pole v typu záznamu je splněna. Specifikace pole je splněna, pokud platí některá z následujících možností:

  • Název pole odpovídající identifikátoru specifikace existuje v záznamu a přidružená hodnota odpovídá typu specifikace.

  • Specifikace je označena jako volitelná a v záznamu se nenajde žádný odpovídající název pole.

Odpovídající hodnota může obsahovat názvy polí, které nejsou uvedené v seznamu specifikací polí, pokud je otevřený a pouze pokud je typ záznamu otevřený.

Typy funkcí

Jakákoli hodnota funkce odpovídá primitivnímu typu function, který neukládá žádná omezení typů formálních parametrů funkce nebo návratové hodnoty funkce. Vlastní hodnota typu funkce slouží k umístění omezení typů na podpisy vyhovujících hodnot funkce.

function-type:
      function ( parametr-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:
      parametr-specification
optional-parameter-specification-list:
      optional-parameter-specification
      optional-parameter-specification
, optional-parameter-specification-list
optional-parameter-specification:

      optionalparametr-specification
parametr-specification:
      parameter-name parameter-type
function-return-type:
      assertion
tvrzení:

      as nullable-primitive-type

Výsledkem vyhodnocení typu funkce je hodnota typu typu, jejíž základní typ je function.

Následující příklady ilustrují syntaxi deklarování typů funkcí:

type function (x as text) as number 
type function (y as number, optional z as text) as any

Hodnota funkce odpovídá typu funkce, pokud je návratový typ hodnoty funkce kompatibilní s návratovým typem typu funkce a každá specifikace parametru typu funkce je kompatibilní s pozičním formálním parametrem funkce. Specifikace parametru je kompatibilní s formálním parametrem, pokud je zadaný typ parametru kompatibilní s typem formálního parametru a specifikace parametru je nepovinná, pokud je formální parametr volitelný.

Formální názvy parametrů jsou ignorovány pro účely určení shody typu funkce.

Zadání parametru jako volitelné implicitně způsobí, že jeho typ má hodnotu null. Následující typy funkcí vytvářejí identické typy:

type function (optional x as text) as any
type function (optional x as nullable text) as any

Typy tabulek

Hodnota typu tabulky slouží k definování struktury hodnoty tabulky.

typ tabulky:
      tabletyp řádku
typ řádku:

      [ field-specification-listopt ]

Výsledkem vyhodnocení typu tabulky je hodnota typu, jejíž základní typ je table.

Typ řádku tabulky určuje názvy sloupců a typy sloupců tabulky jako uzavřený typ záznamu. Aby všechny hodnoty tabulky odpovídaly typu table, typ řádku je typ record (prázdný typ otevřeného záznamu). Tabulka typů je tedy abstraktní, protože žádná hodnota tabulky nemůže mít tabletyp řádku (ale všechny hodnoty tabulky mají typ řádku, který je kompatibilní s typem tableřádku typu). Následující příklad ukazuje výstavbu typu tabulky:

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

Hodnota typu tabulky také nese definici klíčů hodnoty tabulky. Klíč je sada názvů sloupců. Jako primární klíč tabulky lze určit maximálně jeden klíč. (V jazyce M nemají klíče tabulky žádný sémantický význam. U externích zdrojů dat, jako jsou databáze nebo datové kanály OData, je ale běžné definovat klíče nad tabulkami. Power Query používá klíčové informace ke zlepšení výkonu pokročilých funkcí, jako jsou operace spojení mezi zdroji.)

Standardní funkce Type.TableKeysknihovny , Type.AddTableKeya Type.ReplaceTableKeys lze použít k získání klíčů typu tabulky, přidat klíč k typu tabulky a nahradit všechny klíče typu tabulky, v uvedeném pořadí.

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

Typy s povolenou hodnotou Null

Pro libovolnou type Tvariantu s možnou hodnotou null lze odvodit pomocí typu nullable:

nullable-type:
      nullabletyp

Výsledek je abstraktní typ, který umožňuje hodnoty typu T nebo hodnota null.

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

Ascription T type nullable se snižuje na index nebo type type null T. (Vzpomeňte si, že typy s možnou hodnotou null jsou abstraktní a žádná hodnota nemůže být přímo abstraktního typu.)

Value.Type(42 as nullable number)       // type number
Value.Type(null as nullable number)     // type null

Standardní funkce Type.IsNullable knihovny a Type.NonNullable lze je použít k otestování typu s možnou hodnotou null a k odebrání hodnoty nullability z typu.

Následující blokování (pro libovolnou type T):

  • type T je kompatibilní s type nullable T
  • Type.NonNullable(type T) je kompatibilní s type T

Toto jsou párové ekvivalenty (pro libovolnou 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

Přiřazený typ hodnoty

Přiřazený typ hodnoty je typ , ke kterému je hodnota deklarována tak, aby odpovídala .

Hodnota může být přiřazena typ pomocí funkce Value.ReplaceTypeknihovny . Tato funkce buď vrátí novou hodnotu s přiřazeným typem, nebo vyvolá chybu, pokud je nový typ nekompatibilní s hodnotou.

Pokud je hodnota přiřazena typu, dojde pouze k omezené kontrole shody:

  • Přiřazený typ musí být non-abstraktní, non-nullable a kompatibilní s vnitřní (nativní) primitivní typ hodnoty.
  • Pokud je přiřazen vlastní typ, který definuje strukturu, musí odpovídat struktuře hodnoty.
    • Pro záznamy: Typ musí být uzavřen, musí definovat stejný počet polí jako hodnota a nesmí obsahovat žádná nepovinná pole. (Názvy polí a typy polí typu nahradí ty, které jsou aktuálně přidružené k záznamu. Existující hodnoty polí však nebudou kontrolovány u nových typů polí.)
    • Pro tabulky: Typ musí definovat stejný počet sloupců jako hodnota. (Názvy sloupců a typy sloupců typu nahradí ty, které jsou aktuálně přidružené k tabulce. Existující hodnoty sloupců se však nebudou kontrolovat u nových typů sloupců.)
    • Pro funkce: Typ musí definovat stejný počet požadovaných parametrů a stejný počet volitelných parametrů jako hodnota. (Parametr typu a návratové kontrolní výrazy a jeho názvy parametrů nahradí ty, které jsou přidruženy k aktuálnímu typu hodnoty funkce. Nové kontrolní výrazy však nebudou mít žádný vliv na skutečné chování funkce.)
    • Pro seznamy: Hodnota musí být seznam. (Existující položky seznamu se však nebudou kontrolovat u nového typu položky.)

Funkce knihovny se můžou rozhodnout vypočítat a připsat komplexní typy výsledkům na základě přiřazených typů vstupních hodnot.

Přiřazený typ hodnoty lze získat pomocí funkce Value.Typeknihovny . Příklad:

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

Ekvivalence typů a kompatibilita

V jazyce M není definována ekvivalence typů. Implementace jazyka M se může volitelně rozhodnout použít vlastní pravidla k porovnání rovnosti mezi hodnotami typu. Porovnání dvou hodnot typu rovnosti by se mělo vyhodnotit true , jestli jsou považovány za stejné implementací, a false jinak. V oboupřípadechch Všimněte si, že v rámci dané implementace může porovnání některých identických hodnot typu (například (type text) = (type text)) vrátit true, zatímco porovnávání jiných (například (type [a = text]) = (type [a = text])) nemusí.

Kompatibilita mezi daným typem a primitivním typem s možnou hodnotou null lze určit pomocí funkce Type.Isknihovny, která přijímá libovolnou hodnotu typu jako první a hodnotu primitivního typu s možnou hodnotou null jako druhý argument:

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

V jazyce M není podporována kompatibilita daného typu s vlastním typem.

Standardní knihovna obsahuje kolekci funkcí pro extrakci definujících charakteristik z vlastního typu, takže je možné implementovat specifické testy kompatibility jako výrazy M. Níže jsou uvedeny některé příklady; Úplné podrobnosti najdete ve specifikaci knihovny M.

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