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≤n ⟨i, 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⟩ ∈ F ⋀ n1 = 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≤n ⟨i, C⟩
Cn to zestaw wszystkich uporządkowanych sekwencji n typów kolumn.
(11) C := ( ⋃0≤i≤∞ Ci ) ∖ { Cm | ⟨a, ⟨n1, t1⟩⟩, ⟨b, ⟨n2, t2⟩⟩ ∈ Cm ⋀ n1 = 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 ∪ TR ∪ T 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 t ∈ T = t dopuszczana do wartości null
(26) NonNullable(nullable t ∈ T) = 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" : ≤ : B ← T × 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) ta ≤ tb ∧ tb ≤ t c → ta ≤ t 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 ∈ TN ∧ ta ≤ ta → NonNullable(t) ≤ NonNullable(t)
Jeśli dwa typy są zgodne, odpowiedniki nienależące do wartości są również zgodne.
(32) ≤ null t ∈ TN
Typ pierwotny null jest zgodny ze wszystkimi typami dopuszczanymi wartości null.
(33) t ∉ TN ≤ 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 F → t ≤
Wszystkie typy funkcji są zgodne z funkcją .
(36) t ∈ T L → t ≤ listy
Wszystkie typy list są zgodne z listą .
(37) t ∈ T R → t ≤ rekordu
Wszystkie typy rekordów są zgodne z rekordem .
(38) t ∈ T T → t ≤ tabeli
Wszystkie typy tabel są zgodne z tabelą .
(39) ta ≤ t b ↔ 〖ta〗≤〖tb〗
Typ listy jest compaible z innym typem listy, jeśli typy elementów są zgodne i na odwrót.
(40) ta ∈ TF = ⟨ pa, p* ⟩, tb ∈ TF = ⟨ p, p* ⟩ ∧ p a ≤ pb → ta ≤ t b
Typ funkcji jest zgodny z innym typem funkcji, jeśli zwracane typy są zgodne, a listy parametrów są identyczne.
(41) ta ∈ TR, tb ∈ TR• → t a ≰ t b
Typ otwartego rekordu nigdy nie jest zgodny z typem zamkniętego rekordu.
(42) ta ∈ TR• = ⟨false, Φ⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ t b
Typ zamkniętego rekordu jest zgodny z inaczej identycznym typem otwartego rekordu.
(43) ta ∈ TRo = ⟨true, (Φ, ⟨true, n, any⟩)⟩, tb ∈ TRo = ⟨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) ta ∈ TR = ⟨b, (Φ, ⟨β, n, u a⟩)⟩, tb ∈ TR = ⟨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) ta ∈ TR = ⟨b, (Φ, ⟨false, n, u⟩)⟩, tb ∈ TR = ⟨b, (Φ, ⟨true, n, u⟩)⟩ → ta ≤ t b
Typ rekordu z polem nie opcjonalnym jest zgodny z typem rekordu identycznym, ale dla tego pola jest opcjonalne.
(46) ta ∈ TRo = ⟨true, (Φ, ⟨b, n, u⟩)⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ t b
Typ otwartego rekordu jest zgodny z innym typem otwartego rekordu z mniejszą liczbą pól.
(47) ta ∈ T = (Φ, ⟨i, ⟨n, ua⟩⟩), tb ∈ TT = (Φ, ⟨i, ⟨n, ub⟩⟩) ∧ ua ≤ ub b → t a ≤ t 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.
DOKUMENTACJA
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