Típusok a Power Query M képletnyelvében
A Power Query M képletnyelve hasznos és kifejező adategyesítési nyelv. De van néhány korlátozás. Például a típusrendszer nincs erős kényszerítve. Bizonyos esetekben szigorúbb ellenőrzésre van szükség. Szerencsére az M egy beépített kódtárat biztosít, amely támogatja a típusokat, hogy az erősebb ellenőrzés megvalósítható legyen.
A fejlesztőknek alaposan ismerniük kell a típusrendszert, hogy ezt bármilyen általánossággal elvégezhessék. És bár a Power Query M nyelvi specifikációja jól magyarázza a típusrendszert, nem hagy néhány meglepetést. A függvénypéldányok ellenőrzéséhez például össze kell hasonlítani a kompatibilitás típusait.
Az M típusú rendszer alapos feltárásával számos ilyen probléma tisztázható, és a fejlesztők számára lehetővé válik a szükséges megoldások kialakítása.
A predikátumszámítás és a naiv halmazelmélet ismeretének megfelelőnek kell lennie a használt jelölés megértéséhez.
PRELIMINARIES
(1) B := { true; false }
A B a logikai értékek tipikus halmaza
(2) N := { érvényes M azonosítók }
N az M összes érvényes nevének halmaza. Ez máshol van definiálva.
(3) P := ⟨B, T⟩
A P függvényparaméterek halmaza. Mindegyik lehetséges, hogy nem kötelező, és típussal rendelkezik. A paraméternevek irrelevánsak.
(4) Pn := ⋃0≤i≤n ⟨i, Pi⟩
A Pn az n függvényparaméterek összes rendezett sorozatának halmaza.
(5) P := ⋃*P i
A P* a függvényparaméterek összes lehetséges sorozatának halmaza a 0-tól felfelé.
(6) F := ⟨B, N, T⟩
F az összes rekordmező halmaza. Minden mező választható, van egy neve és egy típusa.
(7) Fn := ∏0≤i≤n F
Fn az n rekordmezők összes halmaza.
(8) F := ( ⋃* Fi ) ∖ { F | ⟨b1, n1, t1⟩, ⟨b2, n2, t2⟩ ∈ F ⋀ n1n =
Az F* a rekordmezők összes halmazának (bármilyen hosszúságú) halmaza, kivéve azokat a készleteket, ahol több mező neve azonos.
(9) C := ⟨N,T⟩
A C a táblák oszloptípusainak halmaza. Minden oszlopnak van neve és típusa.
(10) Cn ⊂ ⋃0≤i≤n ⟨i, C⟩
A Cn az n oszloptípusok összes rendezett sorozatának halmaza.
(11) C := ( ⋃0≤i≤∞* Ci ) ∖ { Cm | ⟨a, ⟨n1, t1⟩⟩, ⟨b, ⟨n2, t2⟩⟩ ∈ Cm ⋀ n1 =
A C* az oszloptípusok összes (tetszőleges hosszúságú) kombinációjának halmaza, kivéve azokat, amelyekben egynél több oszlop neve azonos.
M TÍPUSOK
(12) TF := ⟨P, P⟩*
A függvénytípusok visszatérési típusból és nulla vagy több függvényparaméter rendezett listájából állnak.
(13) TL :=〖T〗
A listatípust egy adott típus (az úgynevezett "elemtípus") jelöli, kapcsos zárójelekbe burkolva.
Mivel a kapcsos zárójeleket a metalanguage-ban használják, 〖 〗 zárójeleket használ ebben a dokumentumban.
(14) TR := ⟨B, F⟩*
A rekordtípusnak van egy jelölője, amely jelzi, hogy "nyitott", és nulla vagy több rendezetlen rekordmezőt tartalmaz.
(15) TRo := ⟨true, F⟩
(16) TR• := ⟨false, F⟩
A TRo és a TR• a nyitott és zárt rekordtípusok jelölési parancsikonjai.
(17) T T := C *
A táblázattípus nulla vagy több oszloptípus rendezett sorozata, ahol nincsenek névütközések.
(18) TP := { any; none; null; logikai; szám; idő; dátum; datetime; datetimezone; duration; text; binary; type; list; record; table; function; anynonnull }
A primitív típus az M kulcsszavak listájából származik.
(19) T N := { tn, u ∈ T | tn = u+null } = nullable t
Bármely típus a "nullable" kulcsszóval is megjelölhető null értékűként.
(20) T := TF ∪ TL ∪ TR ∪ T∪ T P ∪ T N
Az összes M típus halmaza az alábbi hat típuscsoport egyesítője:
Függvénytípusok, listatípusok, rekordtípusok, táblatípusok, primitív típusok és null értékű típusok.
FÜGGVÉNYEK
Egy függvényt kell definiálni: Nemnullable : T ← T
Ez a függvény egy típust vesz fel, és egy egyenértékű típust ad vissza, kivéve, ha nem felel meg a null értéknek.
IDENTITÁSOK
Bizonyos identitásokra szükség van bizonyos speciális esetek meghatározásához, és segíthet a fentiek tisztázásában is.
(21) null értékű bármely = bármely
(22) null értékű anynonnull = bármely
(23) nullable null = null
(24) nullable none = null
(25) nullable nullable t ∈ T = nullable t
(26) NonNullable(nullable t ∈ T) = NonNullable(t)
(27) NonNullable(any) = anynonnull
TÍPUSKOMPATIBILITÁS
Máshol meghatározottak szerint az M típus akkor és csak akkor egy másik M típussal kompatálható, ha az első típusnak megfelelő összes érték is megfelel a második típusnak.
Itt definiálunk egy kompatibilitási kapcsolatot, amely nem függ a megfelelő értékektől, és maguk a típusok tulajdonságain alapulnak. A jelen dokumentumban meghatározott reláció várhatóan teljesen egyenértékű az eredeti szemantikai definícióval.
A "kompatibilis" kapcsolat: ≤: B ← T × T
Az alábbi szakaszban a kisbetűs t mindig az M típust, a T elemét jelöli.
A *
(28) t ≤ t
Ez a kapcsolat reflexív.
(29) ta ≤ t b ∧ t b ≤ t c → ta ≤ t c
Ez a kapcsolat tranzitív.
(30) egyik sem ≤ ≤
Az M-típusok rácsot alkotnak ezen a kapcsolaton keresztül; egyik sem az alsó, és bármelyik a felső.
(31) ta, tb ∈ TN ∧ t ≤ t→Nemnullable(ta) ≤ Nemnullable(tb)
Ha két típus kompatibilis, akkor a Nemnullable-ekvivalensek is kompatibilisek.
(32) null ≤ t ∈ TN
A primitív null típus kompatibilis az összes null értékű típussal.
(33) t ∉ TN ≤ anynonnull
Minden nemnull típus kompatibilis az anynonnull használatával .
(34) Nemnullable(t) ≤ t
A nemnullible típus kompatibilis a null értékű egyenértékűvel.
(35) t ∈ TF → t ≤ függvény
Minden függvénytípus kompatibilis a függvényekkel .
(36) t ∈ TL → t ≤ lista
Minden listatípus kompatibilis a listával .
(37) t ∈ TR → t ≤ rekord
Minden rekordtípus kompatibilis a rekordokkal .
(38) t ∈ T T → t ≤ tábla
Minden táblatípus kompatibilis a táblázattal .
(39) ta ≤ t b ↔ 〖ta〗≤〖tb〗
Ha az elemtípusok kompatibilisek, és fordítva, egy listatípus összeférhető egy másik listatípussal.
(40) ta ∈ TF = ⟨ p a, * ⟩, tb ∈ TF = ⟨ pb, * ⟩ ∧ pa ≤ p b → ta ≤ t b
A függvénytípusok kompatibilisek egy másik függvénytípussal, ha a visszatérési típusok kompatibilisek, és a paraméterlisták azonosak.
(41) ta ∈ TRo, tb ∈ TR• → ta ≰ t b
A nyitott rekordtípusok soha nem kompatibilisek a zárt rekordtípusokkal.
(42) ta ∈ TR• = ⟨false, Φ⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ t b
A zárt rekordtípus kompatibilis egy egyébként azonos nyitott rekordtípussal.
(43) ta ∈ TRo = ⟨true, (Φ, ⟨true, n, any⟩)⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ t b ∧ t b ≤ t a
Két nyitott rekordtípus összehasonlításakor figyelmen kívül hagyható egy tetszőleges típusú mező.
(44) ta ∈ TR = ⟨b, (Φ, ⟨β, n, ua⟩)⟩, tb ∈ TR = ⟨b, (Φ, ⟨β, n, ub⟩)⟩ ∧ ua ≤ ub → ta ≤ t b
Ha a mező neve és választhatósága azonos, és az említett mezőtípusok kompatibilisek, két rekordtípus kompatibilis egy mezővel.
(45) ta ∈ TR = ⟨b, (Φ, ⟨false, n, u⟩)⟩, tb ∈ TR = ⟨b, (Φ, ⟨true, n, u⟩)⟩ → ta ≤ t b
A nem választható mezővel rendelkező rekordtípusok kompatibilisek egy azonos rekordtípussal, de az adott mező nem kötelező.
(46) ta ∈ TRo = ⟨true, (Φ, ⟨b, n, u⟩)⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ t b
A nyitott rekordtípus kompatibilis egy másik, egy kevesebb mezővel rendelkező nyitott rekordtípussal.
(47) ta ∈ T = (Φ, ⟨i, ⟨n, ua⟩⟩), tb ∈ T = (Φ, ⟨i, ⟨n, ub⟩⟩) ∧ u a ≤ ub → ta ≤ t b
A táblázattípus kompatibilis egy második táblázattípussal, amely azonos, de egy eltérő típusú oszlop esetében, ha az oszlop típusai kompatibilisek.