Typy

Hodnota typu je hodnota, ktorá klasifikuje iné hodnoty. Znamená to, že hodnota, ktorá je klasifikovaná typom , zodpovedá danmu typu. Systém typov jazyka M sa skladá z nasledujúcich druhov typov:

  • Jednoduché typy, ktoré klasifikujú primitívne hodnoty (binary, , datetimedate, datetimezone, duration, list, logical, null, number, record, text, , time, type) a zahŕňajú aj množstvo abstraktných typov (function, table, anyanynonnull a none)

  • Typy záznamov, ktoré klasifikujú hodnoty záznamu na základe názvov polí a typov hodnôt

  • Typy zoznamu, ktoré klasifikujú zoznamy pomocou jedného základného typu položky

  • Typy funkcií, ktoré klasifikujú hodnoty funkcií na základe typov ich parametrov a vrátených hodnôt

  • Typy tabuľky, ktoré klasifikujú hodnoty tabuľky na základe názvov stĺpcov, typov stĺpcov a kľúčov

  • Typy s povolenou hodnotou Null, ktoré klasifikujú hodnotu null okrem všetkých hodnôt klasifikovaných základným typom

  • Typy typov, ktoré klasifikujú hodnoty, ktoré sú typmi

Množina primitívnych typov zahŕňa typy primitívnych hodnôt a počet abstraktných typov, ktoré sú typmi, ktoré jednoznačne nekomercujú žiadne hodnoty: function, table, anyanynonnull a none. Všetky hodnoty funkcie spĺňajú abstraktný typ function, všetky hodnoty tabuľky s abstraktným typom table, všetky hodnoty abstraktného typu any, všetky hodnoty bez hodnoty null s abstraktným typom anynonnulla žiadne hodnoty abstraktného typu none. Výraz typu none musí vyvolať chybu alebo sa nedá ukončiť, pretože by nebolo možné vytvoriť žiadnu hodnotu, ktorá zodpovedá typu none. Všimnite si, že primitívne typy function a table sú abstraktné, pretože žiadna funkcia alebo tabuľka nie je priamo týchto typov. Primitívne typy record a list sú ne abstraktné, pretože predstavujú otvorený záznam bez definovaných polí resp. zoznam typu ľubovoľné.

Všetky typy, ktoré nie sú členmi uzavretej množiny primitívnych typov plus ich nulovateľné náprotivky sa súhrnne označujú ako vlastné typy. Vlastné typy možno zapísať pomocou type-expression:

type-expression:
      primary-expression

      typeprimary-type
Typ:
      primary-expression
      primary-type
primary-type:
      primitive-type
      record-type
      list-type
      function-type
      table-type
      nullable-type
primitive-type:
jedno zo
      any anynonnull binary date datetime datetimezone duration function list logical
      none null number record table text time type

Názvy primitive-typekontextové kľúčové slová rozpoznané iba v kontexte typu . Použitie zátvoriek v kontexte typu vracia gramatiku späť do kontextu regulárneho výrazu a na presun späť do kontextu typu vyžaduje použitie kľúčového slova typu. Ak chcete napríklad vyvolať funkciu v kontexte typu , môžete použiť zátvorky:

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

Zátvorky možno použiť aj na prístup k premennej, ktorej názov je v súlade s názvom primitive-type :

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

Nasledujúci príklad definuje typ, ktorý klasifikuje zoznam čísel:

type { number }

Podobne platí, že nasledujúci príklad definuje vlastný typ, ktorý klasifikuje záznamy s povinnými poľami s názvami X a Y , ktorých hodnoty sú čísla:

type [ X = number, Y = number ]

Pripísaný typ hodnoty sa získa pomocou funkcie štandardnej knižnice Value.Type, ako je to znázornené v nasledujúcich príkladoch:

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

Operátor sa is používa na určenie, či je typ hodnoty kompatibilný s daným typom, ako je to znázornené v nasledujúcich príkladoch:

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

Operátor as skontroluje, či je hodnota kompatibilná s daným typom, a ak nie je, vyvolá chybu. V opačnom prípade vráti pôvodnú hodnotu.

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

Všimnite si, že operátory is a as akceptujú ako svoj pravý operand iba nulovateľné primitívne typy. Jazyk M neposkytuje prostriedky na kontrolu zhody hodnôt s vlastnými typmi.

Typ X je kompatibilný s typom Y vtedy a len vtedy, ak všetky hodnoty, ktoré zodpovedajú X , zodpovedajú Yaj . Všetky typy sú kompatibilné s typom any a žiadne typy (okrem none samotného) nie sú kompatibilné s typom none. V nasledujúcom grafe sa zobrazuje vzťah kompatibility. (Kompatibilita typov je reflexívna a tranzitívna. Tvorí mriežku s typom any ako vrchnou a typom none ako spodnou hodnotou.) Názvy abstraktných typov sú nastavené kurzívou.

Kompatibilita typov

Pre hodnoty typov sú definované nasledujúce operátory:

Operátor Result
x = y Equal
x <> y Nerovná sa
x ?? y Coalesce

Natívny typ hodnôt typov je vnútorný typ type.

Primitívne typy

Typy v jazyku M tvoria nesúvislú hierarchiu, ktorej koreňom je typ any, čo je typ, ktorý klasifikuje všetky hodnoty. Ľubovoľná hodnota jazyka M zodpovedá presne jednému primitívnemu podtypu any. Uzavretá množina primitívnych typov odvodených od typu any je nasledovná:

  • type null, ktorý klasifikuje hodnotu null.
  • type logical, ktorý klasifikuje hodnoty true a false.
  • type number, ktorý klasifikuje číselné hodnoty.
  • type time, ktorý klasifikuje časové hodnoty.
  • type date, ktorý klasifikuje dátumové hodnoty.
  • type datetime, ktorý klasifikuje hodnoty datetime.
  • type datetimezone, ktorý klasifikuje hodnoty datetimezone.
  • type duration, ktorý klasifikuje hodnoty trvania.
  • type text, ktorý klasifikuje textové hodnoty.
  • type binary, ktorý klasifikuje binárne hodnoty.
  • type type, ktorý klasifikuje hodnoty typov.
  • type list, ktorý klasifikuje hodnoty zoznamu.
  • type record, ktorý klasifikuje hodnoty záznamu.
  • type table, ktorý klasifikuje hodnoty tabuľky.
  • type function, ktorý klasifikuje hodnoty funkcie.
  • type anynonnull, ktorý klasifikuje všetky hodnoty okrem null.
  • type none, ktorý klasifikuje žiadne hodnoty.

Ľubovoľný typ

Typ any je abstraktný, klasifikuje všetky hodnoty v jazyku M a všetky typy v jazyku M sú kompatibilné s any. Premenné typu any možno naviazať na všetky možné hodnoty. Keďže any je abstraktná, nemožno ju pripísať hodnotám – to znamená, že žiadna hodnota nie je priamo typu any.

Typy zoznamu

Každá hodnota, ktorá je zoznamom, zodpovedá vnútornému typu list, ktorý nekladie žiadne obmedzenia na položky v rámci hodnoty zoznamu.

list-type:
      {item-type}
item-type:
      Typ

Výsledkom vyhodnocovania hodnoty list-type je hodnota typu zoznamu, ktorej základný typ je list.

Nasledujúce príklady znázorňujú syntax na deklarovanie homogénnych typov zoznamu:

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

Hodnota zodpovedá typu zoznamu, ak je táto hodnota zoznamom a každá položka v tejto hodnote zodpovedá typu položky zoznamu.

Typ položky typu zoznamu označuje väzbu: všetky položky zodpovedajúceho zoznamu zodpovedajú typu položky.

Typy záznamu

Každá hodnota, ktorá je záznamom, zodpovedá vnútornému typu záznamu, ktorý nekladie žiadne obmedzenia názvy alebo hodnoty polí v rámci hodnoty záznamu. Hodnota typu záznamu sa používa na obmedzenie množiny platných názvov, ako aj typov hodnôt, ktoré sú povolené na priradenie k týmto názvom.

record-type:
      [open-record-marker]
      [field-specification-listopt]
      [field-specification-list , open-record-marker]
field-specification-list:
      field-specification
      field-specification,field-specification-list
field-specification:

      optionalopt field-name field-type-specificationopt
field-type-specification:

      =field-type
field-type:
      zadať
open-record-marker:

      ...

Výsledkom vyhodnocovania hodnoty record-type je hodnota typu, ktorej základný typ je record.

Nasledujúce príklady znázorňujú syntax na deklarovanie typov záznamov:

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

Typy záznamov sú predvolene uzavreté , čo znamená, že ďalšie polia, ktoré sa nenachádzajú v hodnote fieldspecification-list , nemajú povolené nachádzať sa v zodpovedajúcich hodnotách. Zahrnutím openrecord-marker do typu záznamu sa deklaruje typ, ktorý má byť otvorený, čo povoľuje polia, ktoré nie sú prítomné v zozname špecifikácií poľa. Nasledujúce dva výrazy sú rovnocenné:

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

Hodnota zodpovedá typu záznamu, ak je táto hodnota záznamom a je splnená každá špecifikácia poľa v type záznamu. Špecifikácia poľa je splnená, ak je pravda ľubovoľná z nasledujúcich možností:

  • V zázname existuje názov poľa zodpovedajúci identifikátoru špecifikácie, a súvisiaca hodnota zodpovedá typu špecifikácie

  • Špecifikácia je označená ako voliteľná a v zázname sa nenašiel žiadny zodpovedajúci názov poľa

Zodpovedajúca hodnota môže obsahovať názvy polí, ktoré nie sú uvedené v zozname špecifikácií polí, vtedy a len vtedy, ak je typ záznamu otvorený.

Typy funkcií

Ľubovoľná hodnota funkcie zodpovedá primitívnemu typu function, ktorý nekladie žiadne obmedzenia na typy formálnych parametrov funkcie alebo vrátenú hodnotu funkcie. Vlastná hodnota typu funkcie sa používa na umiestnenie obmedzení typu na podpisy zodpovedajúcich hodnôt funkcií.

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

      optionalparameter-specification
parameter-specification:
      parameter-name parameter-type
function-return-type:
      assertion
Tvrdenie:

      asnullable-primitive-type

Výsledkom vyhodnocovania hodnoty function-type je hodnota typu, ktorej základný typ je function.

Nasledujúce príklady znázorňujú syntax na deklarovanie typov funkcií:

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

Hodnota funkcie zodpovedá typu funkcie, ak je vrátený typ hodnoty funkcie kompatibilný s vráteným typom typu funkcie a každá špecifikácia parametra typu funkcie je kompatibilná s pozične zodpovedajúcim formálnym parametrom funkcie. Špecifikácia parametra je kompatibilná s formálnym parametrom, ak je zadaná hodnota parameter-type kompatibilná s typom formálneho parametra, a špecifikácia parametra je voliteľná, ak je voliteľný formálny parameter.

Názvy formálnych parametrov sa na účely stanovenia zhody typu funkcie ignorujú.

Ak parameter zadáte ako voliteľný, implicitne sa jeho typ stane nulovateľným. Nižšie sú uvedené nasledujúce typy identických funkcií:

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

Typy tabuľky

Na definovanie štruktúry hodnoty tabuľky sa použije hodnota table-type.

table-type:
      tablerow-type
row-type:

      [field-specification-listopt]

Výsledkom vyhodnocovania hodnoty table-type je hodnota typu, ktorej základný typ je table.

Typ riadka tabuľky určuje názvy stĺpcov a typy stĺpcov tabuľky ako uzavretý typ záznamu. Tak, aby všetky hodnoty tabuľky zodpovedali typu table, jeho typ riadka je typ record (typ prázdneho otvoreného záznamu). Preto typ tabuľky je abstraktný, pretože žiadna hodnota tabuľky nemôže mať typ riadka typu table(ale všetky hodnoty tabuľky majú typ riadka, ktorý je kompatibilný s typom riadka typu table). Nasledujúci príklad znázorňuje konštrukciu typu tabuľky:

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 tabuľky obsahuje aj definíciu kľúčov hodnoty tabuľky. Kľúč je množina názvov stĺpcov. Ako primárny kľúč tabuľky možno určiť na najviac jeden kľúč. (V jazyku M nemajú kľúče tabuľky žiadny sémantický význam. Je však bežné, že v prípade externých zdrojov údajov, ako sú napríklad databázy alebo informačné kanály OData, môžete definovať kľúče v tabuľkách. Power Query používa informácie o kľúčoch na zlepšenie výkonu pokročilých funkcií, ako sú napríklad operácie spojenia krížového zdroja.)

Štandardné funkcie Type.TableKeysknižnice , Type.AddTableKeya Type.ReplaceTableKeys možno použiť na získanie kľúčov typu tabuľky, pridanie kľúča do typu tabuľky a nahradenie všetkých kľúčov typu tabuľky.

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

Pre všetky type Tmožno variant s povolenou hodnotou null odvodiť pomocou nullable-type:

nullable-type:
      nullabletyp

Výsledkom je abstraktný typ, ktorý povoľuje hodnoty typu T alebo hodnotu null.

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

Pripísanie T redukuje type nullablepripísanie type null alebo typeT. (Pripomíname, že typy s povolenou hodnotou null sú abstraktné a žiadna hodnota nemôže byť priamo abstraktného typu.)

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

Štandardné funkcie Type.IsNullable knižnice a Type.NonNullable možno použiť na otestovanie nulovateľnosti typu a na odstránenie nulovateľnosti z typu.

Platí nasledujúce (pre ľubovoľné type T):

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

Nižšie sú uvedené párové ekvivalenty (pre ľubovoľné 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

Pripísaný typ hodnoty

Pripísaný typ hodnoty je typ , ku ktorému je hodnota deklarovaná ako zodpovedajúca.

Hodnotu možno pripísať typu pomocou funkcie Value.ReplaceTypeknižnice . Táto funkcia buď vráti novú hodnotu s pripisovaným typom alebo vyvolá chybu, ak je nový typ nekompatibilný s hodnotou.

Pri pripísaní typu hodnote sa vykoná len obmedzená kontrola zhody:

  • Pripisovaný typ musí byť ne abstraktný, nenulovateľný a kompatibilný s vnútorným (natívnym) primitívnym typom hodnoty.
  • Keď sa pripisuje vlastný typ, ktorý definuje štruktúru, musí zodpovedať štruktúre hodnoty.
    • Pre záznamy: Typ musí byť uzavretý, musí definovať rovnaký počet polí ako hodnota a nesmie obsahovať žiadne voliteľné polia. (Názvy polí a typy polí typu nahradia tie, ktoré sú aktuálne priradené k záznamu. Existujúce hodnoty polí sa však pre nové typy polí nebudú kontrolovať.)
    • Pre tabuľky: Typ musí definovať rovnaký počet stĺpcov ako hodnota. (Názvy stĺpcov a typy stĺpcov typu nahradia tie, ktoré sú aktuálne priradené k tabuľke. Existujúce hodnoty stĺpcov sa však pre nové typy stĺpcov nebudú kontrolovať.)
    • Pre funkcie: Typ musí definovať rovnaký počet požadovaných parametrov, ako aj rovnaký počet voliteľných parametrov ako hodnota. (Parameter typu a vrátené kontrolné výrazy, ako aj názvy jeho parametrov, nahradia tie priradené k aktuálnemu typu hodnoty funkcie. Nové kontrolné výrazy však nebudú mať žiadny vplyv na skutočné správanie funkcie.)
    • Pre zoznamy: Hodnota musí byť zoznam. (Existujúce položky zoznamu sa však nebudú kontrolovať pre nový typ položky.)

Funkcie knižnice sa môžu rozhodnúť vypočítať a pripisovať komplexné typy výsledkom na základe pripísaných typov vstupných hodnôt.

Pripísaný typ hodnoty možno získať pomocou funkcie Value.Typeknižnice . Napríklad:

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

Ekvivalencia a kompatibilita typu

Ekvivalencia typu nie je v jazyku M definovaná. Implementácia jazyka M sa môže voliteľne rozhodnúť používať svoje vlastné pravidlá na vykonávanie porovnaní rovnosti medzi hodnotami typu. Porovnanie dvoch hodnôt typu pre rovnosť by sa malo vyhodnotiť s true tým, či sú považované za identické v rámci implementácie, a false v opačnom prípade. V oboch prípadoch musí byť vrátená odpoveď konzistentná, ak sa opakovane porovnávajú rovnaké dve hodnoty. Všimnite si, že v rámci danej implementácie sa môžu porovnať niektoré identické hodnoty typu (napríklad (type text) = (type text)) a iné (napríklad (type [a = text]) = (type [a = text])) sa nemusia porovnávaťtrue.

Kompatibilita medzi daným typom a nulovateľným primitívnym typom možno sa dá určiť pomocou funkcie Type.Isknižnice , ktorá ako svoj prvý argument akceptuje voliteľnú hodnotu typu a ako svoj druhý argument nulovateľnú primitívneho hodnotu typu:

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 jazyku M neexistuje žiadna podpora na určovanie kompatibility daného typu s vlastným typom.

Štandardná knižnica obsahuje kolekciu funkcií na extrahovanie definícií vlastností z vlastného typu, takže konkrétne testy kompatibility možno implementovať ako výrazy jazyka M. Nižšie je uvedených niekoľko príkladov. Podrobné informácie nájdete v špecifikácii knižnice jazyka 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