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
, ,date
datetime
,datetimezone
,duration
,list
,logical
,null
,number
,record
,text
, ,time
,type
) a zahŕňajú aj množstvo abstraktných typov (function
,table
,any
anynonnull
anone
)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
, any
anynonnull
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 anynonnull
a ž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
type
primary-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-type sú kontextové 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 použitím 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ú Y
aj . 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.
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:
optional
opt 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:
optional
parameter-specification
parameter-specification:
parameter-name parameter-type
function-return-type:
assertion
tvrdenie:
as
nullable-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:
table
row-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.TableKeys
knižnice , Type.AddTableKey
a 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 T
možno variant s povolenou hodnotou null odvodiť pomocou nullable-type:
nullable-type:
nullable
typ
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 nullable
pripísanie type null
alebo type
T. (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á stype nullable T
-
Type.NonNullable(type T)
je kompatibilná stype 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.ReplaceType
kniž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.Type
kniž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 true
) sa nemusia porovnávať(type [a = text]) = (type [a = text])
.
Kompatibilita medzi daným typom a nulovateľným primitívnym typom možno sa dá určiť pomocou funkcie Type.Is
kniž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
Súvisiaci obsah
- Typy a konverzie typu
- Typy v jazyku vzorcov Power Query M