Typy w języku formuł Power Query M

Język formuł Power Query M to przydatny i ekspresywny język mashupu danych. Ale ma pewne ograniczenia. Na przykład nie ma silnego wymuszania systemu typów. W niektórych przypadkach potrzebna jest bardziej rygorystyczna walidacja. Na szczęście język M udostępnia wbudowaną bibliotekę z obsługą typów, aby zapewnić lepszą walidację.

Deweloperzy powinni mieć dokładną wiedzę na temat systemu typów, aby to zrobić z jakąkolwiek ogólną wiedzą. Podczas gdy specyfikacja języka Power Query M dobrze wyjaśnia system typów, pozostawia kilka niespodzianek. Na przykład walidacja wystąpień funkcji wymaga sposobu porównywania typów pod kątem zgodności.

Dokładniej eksplorując system typów M, można wyjaśnić wiele z tych problemów, a deweloperzy będą mogli tworzyć potrzebne rozwiązania.

Znajomość predykatu rachunkowego i naiwnej teorii zestawów powinna być odpowiednia, aby zrozumieć używaną notację.

WSTĘPNE

(1) B := { true; false }
B to typowy zestaw wartości logicznych

(2) N := { prawidłowych identyfikatorów M }
N to zestaw wszystkich prawidłowych nazw w języku M. Jest to zdefiniowane w innym miejscu.

(3) P := ⟨B, T
P to zestaw parametrów funkcji. Każdy z nich jest prawdopodobnie opcjonalny i ma typ. Nazwy parametrów są nieistotne.

(4) Pn := ⋃0≤i≤ni, Pi⟩
Pn to zestaw wszystkich uporządkowanych sekwencji n parametrów funkcji.

(5) P := ⋃0≤i≤∞P i*
P* to zestaw wszystkich możliwych sekwencji parametrów funkcji, od długości 0 w górę.

(6) F := ⟨B, N, T
F to zestaw wszystkich pól rekordów. Każde pole jest prawdopodobnie opcjonalne, ma nazwę i typ.

(7) Fn := ∏0≤i≤n F
Fn to zestaw wszystkich zestawów n pól rekordów.

(8) F := ( ⋃0≤i≤∞Fi ) ∖ { F | ⟨b1, n1, t1⟩, ⟨b2, n2, t2⟩ ∈ Fn1 = n2 }*
F* to zestaw wszystkich zestawów (o dowolnej długości) pól rekordów, z wyjątkiem zestawów, w których więcej niż jedno pole ma taką samą nazwę.

(9) C := ⟨N,T
C to zestaw typów kolumn dla tabel. Każda kolumna ma nazwę i typ.

(10) Cn ⊂ ⋃0≤i≤ni, C⟩
Cn to zestaw wszystkich uporządkowanych sekwencji n typów kolumn.

(11) C := ( ⋃0≤i≤∞Ci ) ∖ { C m | ⟨a, ⟨n1, t1⟩⟩, ⟨b, ⟨n2, t2⟩⟩ ∈ Cmn1 = n2 }*
C* to zestaw wszystkich kombinacji (dowolnej długości) typów kolumn, z wyjątkiem tych, w których więcej niż jedna kolumna ma taką samą nazwę.

TYPY M

(12) TF := ⟨P, P⟩*
Typ funkcji składa się z typu zwracanego i uporządkowanej listy parametrów funkcji zero lub więcej.

(13) TL :=〖T〗
Typ listy jest wskazywany przez dany typ (nazywany "typem elementu") opakowany w nawiasy klamrowe. Ponieważ nawiasy klamrowe są używane w metalanguage, 〖 〗 nawiasy są używane w tym dokumencie.

(14) TR := ⟨B, F⟩*
Typ rekordu ma flagę wskazującą, czy jest ona "otwarta", a pola rekordów bez kolejności lub więcej.

(15) TRo := ⟨true, F⟩

(16) TR := ⟨false, F⟩
TRo i TR to skróty notacyjne dla typów otwartych i zamkniętych rekordów.

(17) T T := C *
Typ tabeli to uporządkowana sekwencja typów kolumn zero lub więcej, w których nie ma kolizji nazw.

(18) TP := { any; none; null; logical; number; number; time; datetime; datetimezone; duration; duration; text; binary; type; list; table; function; anynonnull }
Typ pierwotny to jeden z tej listy słów kluczowych języka M.

(19) TN := { t n, u ∈ T | t = u+ null } = null t
Każdy typ może być dodatkowo oznaczony jako dopuszczany do wartości null, używając słowa kluczowego "nullable".

(20) T := T F ∪ TL ∪ TRT T∪ T ∪ T N
Zestaw wszystkich typów M jest unią tych sześciu zestawów typów:
Typy funkcji, typy list, typy rekordów, typy tabel, typy pierwotne i typy dopuszczane do wartości null.

FUNKCJE

Należy zdefiniować jedną funkcję: nienależące do nazwy: T ← T
Ta funkcja przyjmuje typ i zwraca typ, który jest równoważny, z wyjątkiem tego, że nie jest zgodny z wartością null.

TOŻSAMOŚCI

Niektóre tożsamości są potrzebne do zdefiniowania niektórych specjalnych przypadków, a także mogą pomóc w wyjaśnieniu powyższych.

(21) dopuszczana wartość null dowolna = dowolna
(22) anynonnull dopuszczana do wartości null = dowolna
(23) nullable null = null
(24) Brak dopuszczalny do wartości null = null
(25) dopuszczana do wartości null tT = t dopuszczana do wartości null
(26) NonNullable(nullable tT) = NonNullable(t)
(27) NonNullable(any) = anynonnull

ZGODNOŚĆ TYPÓW

Zgodnie z definicją gdzie indziej typ M jest komplikowalny z innym typem M, jeśli i tylko wtedy, gdy wszystkie wartości zgodne z pierwszym typem są również zgodne z drugim typem.

Poniżej zdefiniowano relację zgodności, która nie zależy od zgodnych wartości i jest oparta na samych właściwościach typów. Przewiduje się, że ta relacja, zgodnie z definicją w tym dokumencie, jest całkowicie równoważna oryginalnej definicji semantycznej.

Relacja "jest zgodna z" : ≤ : BT × T
W poniższej sekcji małe litery nie zawsze będą reprezentować typ języka M, element T.

Φ będzie reprezentować podzbiór F* lub C*.

(28) t ≤ t
Ta relacja jest refleksyjna.

(29) tatb ∧ tbt ctat c
Ta relacja jest przechodnia.

(30) Brak ≤ żadnych
Typy M tworzą kratę nad tą relacją; żadna nie jest dolna, a każda jest górna.

(31) ta, tb ∈ TNta ≤ taNonNullable(t) ≤ NonNullable(t)
Jeśli dwa typy są zgodne, odpowiedniki nienależące do wartości są również zgodne.

(32) ≤ null tTN
Typ pierwotny null jest zgodny ze wszystkimi typami dopuszczanymi wartości null.

(33) tTN ≤ anynonnull
Wszystkie typy nienadzorowalne są zgodne z anynonnull.

(34) NonNullable(t) ≤ t
Typ nonNullible jest zgodny z równoważnym dopuszczalnym wartością null.

(35) t ∈ funkcja T Ft ≤
Wszystkie typy funkcji są zgodne z funkcją .

(36) t ∈ T Lt ≤ listy
Wszystkie typy list są zgodne z listą .

(37) t T Rt ≤ rekordu
Wszystkie typy rekordów są zgodne z rekordem .

(38) t ∈ T Tt ≤ tabeli
Wszystkie typy tabel są zgodne z tabelą .

(39) tat b ↔ta〗≤〖tb〗
Typ listy jest compaible z innym typem listy, jeśli typy elementów są zgodne i na odwrót.

(40) taTF = ⟨ pa, p* ⟩, tbTF = ⟨ p, p* ⟩ ∧ p apbtat b
Typ funkcji jest zgodny z innym typem funkcji, jeśli zwracane typy są zgodne, a listy parametrów są identyczne.

(41) taTR, tbTRt at b
Typ otwartego rekordu nigdy nie jest zgodny z typem zamkniętego rekordu.

(42) taTR• = ⟨false, Φ⟩, tb ∈TRo = ⟨true, Φ⟩ → tat b
Typ zamkniętego rekordu jest zgodny z inaczej identycznym typem otwartego rekordu.

(43) taTRo = ⟨true, (Φ, ⟨true, n, any⟩)⟩, tbTRo = ⟨true, Φ⟩ → ta ≤ tb∧ t b ≤ t a
Opcjonalne pole o typie dowolnym może być ignorowane podczas porównywania dwóch otwartych typów rekordów.

(44) taTR = ⟨b, (Φ, ⟨β, n, u a⟩)⟩, tbTR = ⟨b, (Φ, ⟨β, n, u b⟩)⟩ ∧ ua ≤ u b→ t a tb b
Dwa typy rekordów różniące się tylko jednym polem są zgodne, jeśli nazwa i opcjonalność pola są identyczne, a typy tych pól są zgodne.

(45) taTR = ⟨b, (Φ, ⟨false, n, u⟩)⟩, tbTR = ⟨b, (Φ, ⟨true, n, u⟩)⟩ → tat b
Typ rekordu z polem nie opcjonalnym jest zgodny z typem rekordu identycznym, ale dla tego pola jest opcjonalne.

(46) taTRo = ⟨true, (Φ, ⟨b, n, u⟩)⟩, tbTRo = ⟨true, Φ⟩ → tat b
Typ otwartego rekordu jest zgodny z innym typem otwartego rekordu z mniejszą liczbą pól.

(47) taT = (Φ, ⟨i, ⟨n, ua⟩⟩), tbTT = (Φ, ⟨i, ⟨n, ub⟩⟩) ∧ uaub b → t at b
Typ tabeli jest zgodny z drugim typem tabeli, który jest identyczny, ale dla jednej kolumny o różnym typie, gdy typy dla tej kolumny są zgodne.

REFERENCJE

Microsoft Corporation (sierpień 2015)
Microsoft Power Query dla specyfikacji języka formuł programu Excel [PDF]
Źródło https://msdn.microsoft.com/library/mt807488.aspx

Microsoft Corporation (n.d.)
Dokumentacja funkcji języka M dodatku Power Query [strona internetowa]
Źródło https://msdn.microsoft.com/library/mt779182.aspx