Typer i Power Query M-formelspråket
Power Query M-formelspråket er et nyttig og uttrykksfullt dataflettingsspråk. Men det har noen begrensninger. Det finnes for eksempel ingen sterk håndhevelse av typesystemet. I noen tilfeller er det nødvendig med en strengere validering. Heldigvis gir M et innebygd bibliotek med støtte for typer for å gjøre sterkere validering mulig.
Utviklere bør ha en grundig forståelse av typesystemet for å kunne gjøre dette med enhver generalitet. Og selv om power query M-språkspesifikasjonen forklarer typesystemet godt, gir det noen overraskelser. Validering av funksjonsforekomster krever for eksempel en måte å sammenligne typer for kompatibilitet på.
Ved å utforske M-typesystemet mer nøye, kan mange av disse problemene avklares, og utviklere vil bli bemyndiget til å lage løsningene de trenger.
Kunnskap om predikatkalkulus og naiv sett teori bør være tilstrekkelig til å forstå notasjonen som brukes.
INNLEDENDE
(1) B := { true; false }
B er det vanlige settet med boolske verdier
(2) N := { gyldige M-identifikatorer }
N er settet med alle gyldige navn i M. Dette er definert et annet sted.
(3) P := ⟨B, T⟩
P er settet med funksjonsparametere. Hver av dem er muligens valgfri, og har en type. Parameternavn er irrelevante.
(4) Pn := ⋃0≤i≤n ⟨i, Pi⟩
Pn er settet med alle ordnede sekvenser av n funksjonsparametere.
(5) P := ⋃*P i
P* er settet med alle mulige sekvenser av funksjonsparametere, fra lengden 0 på opp.
(6) F := ⟨B, N, T⟩
F er settet med alle postfelt. Hvert felt er muligens valgfritt, har et navn og en type.
(7) Fn := ∏0≤i≤n F
Fn er settet med alle sett med n postfelt.
(8) F := ( ⋃* Fi ) ∖ { F | ⟨b1, n1, t1⟩, ⟨b2, n2, t2⟩ ∈ F ⋀ n1n =
F* er settet med alle sett (av en hvilken som helst lengde) av postfelt, bortsett fra settene der mer enn ett felt har samme navn.
(9) C := ⟨N,T⟩
C er settet med kolonnetyper for tabeller. Hver kolonne har et navn og en type.
(10) Cn ⊂ ⋃0≤i≤n ⟨i, C⟩
Cn er settet med alle ordnede sekvenser av n kolonnetyper.
(11) C := ( ⋃* Ci ) ∖ { Cm | ⟨a, ⟨n1, t1⟩⟩, ⟨b, ⟨n2, t2⟩⟩ ∈ Cm ⋀ n1n = }
C* er settet med alle kombinasjoner (av en hvilken som helst lengde) av kolonnetyper, bortsett fra de der mer enn én kolonne har samme navn.
M-TYPER
(12) TF := ⟨P, P⟩*
En funksjonstype består av en returtype, og en sortert liste over null-eller-flere funksjonsparametere.
(13) TL :=〖T〗
En listetype angis av en gitt type (kalt elementtype) innpakket i klammeparenteser.
Siden klammeparenteser brukes i metallfiske, 〖 〗 hakeparenteser brukes i dette dokumentet.
(14) TR := ⟨B, F⟩*
En posttype har et flagg som angir om det er «åpent» og null eller flere usorterte postfelt.
(15) TRo := ⟨true, F⟩
(16) TR• := ⟨false, F⟩
TRo og TR• er notasjonssnarveier for henholdsvis åpne og lukkede oppføringstyper.
(17) TT := C *
En tabelltype er en ordnet sekvens med null-eller-flere kolonnetyper, der det ikke er noen navnekollisjoner.
(18) TP := { any; none; null; logical; number; time; date; datetime; datetimezone; duration; text; binary; type; list; record; table; function; anynonnull }
En primitiv type er én fra denne listen over M-nøkkelord.
(19) TN := { tn, u ∈ T | tn = u+null } = nullable t
Alle typer kan i tillegg merkes som nullstillbare, ved hjelp av nøkkelordet «nullable ».
(20) T := TF ∪ TL ∪ TR ∪ TT ∪ TP ∪ TN
Settet med alle M-typer er unionen av disse seks settene med typer:
Funksjonstyper, listetyper, oppføringstyper, tabelltyper, primitive typer og typer som kan nullstilles.
FUNKSJONER
Én funksjon må defineres: NonNullable : T ← T
Denne funksjonen tar en type, og returnerer en type som tilsvarer, bortsett fra at den ikke samsvarer med nullverdien.
IDENTITETER
Noen identiteter er nødvendig for å definere noen spesielle tilfeller, og kan også bidra til å belyse ovennevnte.
(21) nullable any = any
(22) nullable anynonnull = any
(23) nullverdiverdi = null
(24) nullbar ingen = null
(25) nullbar nullbar t ∈ T = nullbar t
(26) NonNullable(nullable t ∈ T) = NonNullable(t)
(27) NonNullable(any) = anynonnull
TYPEKOMPATIBILITET
Som definert et annet sted, kan en M-type kompateres med en annen M-type hvis og bare hvis alle verdier som samsvarer med den første typen, også samsvarer med den andre typen.
Her er definert en kompatibilitetsrelasjon som ikke er avhengig av samsvarende verdier, og er basert på egenskapene til selve typene. Det forventes at denne relasjonen, som definert i dette dokumentet, er helt lik den opprinnelige semantiske definisjonen.
Relasjonen "er kompatibel med" : ≤ : B ← T × T
I inndelingen nedenfor vil en liten t alltid representere en M-type, et element av T.
En *
(28) t ≤ t
Denne relasjonen er refleksiv.
(29) ta ≤ tb ∧ tb ≤ tc → ta ≤ t c
Denne relasjonen er transitiv.
(30) ingen ≤ ikke ≤ noen
M-typer danner et gitter over denne relasjonen. ingen er nederst, og alle er øverst.
(31) ta, tb ∈ TN ∧ ta ≤ ta → NonNullable(ta) ≤ NonNullable(tb)
Hvis to typer er kompatible, er de ikke-ekvivalentene som ikke kan brukes, også kompatible.
(32) null ≤ t ∈ TN
Primitiv type null er kompatibel med alle typer som kan nullstilles.
(33) t ∉ TN ≤ anynonnull
Alle typer som ikke kanulleres, er kompatible med anynonnull.
(34) NonNullable(t) ≤ t
En type som ikke kan nullstilles, er kompatibel med den nullbare ekvivalenten.
(35) t ∈ TF → t ≤ funksjon
Alle funksjonstyper er kompatible med funksjonen.
(36) t ∈ TL → t ≤ liste
Alle listetyper er kompatible med listen.
(37) t ∈ TR → t ≤ post
Alle oppføringstyper er kompatible med posten.
(38) t ∈ TT → t ≤ tabell
Alle tabelltyper er kompatible med tabellen.
(39) ta ≤ tb ↔ 〖ta〗≤〖tb〗
En listetype kan sammenlignes med en annen listetype hvis elementtypene er kompatible, og omvendt.
(40) ta ∈ TF = ⟨ pa, * ⟩, tb ∈ TF = ⟨ pb, * ⟩ ∧ pa ≤ pb → ta ≤ t b
En funksjonstype er kompatibel med en annen funksjonstype hvis returtypene er kompatible, og parameterlistene er identiske.
(41) ta ∈ TRo, tb ∈ TR• → ta ≰ t b
En åpen posttype er aldri kompatibel med en lukket posttype.
(42) ta ∈ TR• = ⟨false, Φ⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ t b
En lukket posttype er kompatibel med en ellers identisk åpen posttype.
(43) ta ∈ TRo = ⟨true, (Φ, ⟨true, n, any⟩)⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ tb ∧ tb ≤ t a
Et valgfritt felt med hvilken som helst type kan ignoreres når du sammenligner to åpne oppføringstyper.
(44) ten ∈ TR = ⟨b, (Φ, ⟨β, n, ua⟩)⟩, tb ∈ TR = ⟨b, (Φ, ⟨β, n, ub⟩)⟩ ∧ ua ≤ ub → ta ≤ t b
To posttyper som bare varierer med ett felt, er kompatible hvis navnet og valgfriheten til feltet er identisk, og typene nevnte felt er kompatible.
(45) ta ∈ TR = ⟨b, (Φ, ⟨false, n, u⟩)⟩, tb ∈ TR = ⟨b, (Φ, ⟨true, n, u⟩)⟩ → ta ≤ t b
En posttype med et ikke-valgfritt felt er kompatibelt med en posttype identisk, men for at feltet skal være valgfritt.
(46) ta ∈ TRo = ⟨true, (Φ, ⟨b, n, u⟩)⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ t b
En åpen posttype er kompatibel med en annen åpen posttype med ett færre felt.
(47) ta ∈ TT = (Φ, ⟨i, ⟨n, ua⟩⟩), tb ∈ TT = (Φ, ⟨i, ⟨n, ub⟩⟩) ∧ ua ≤ ub → ta ≤ tb b
En tabelltype er kompatibel med en annen tabelltype, som er identisk, men for én kolonne som har en annen type, når typene for denne kolonnen er kompatible.