Power Query M 数式言語の型
Power Query M 数式言語は便利で表現力の高いデータ マッシュアップ言語です。 ただし、これにはいくつかの制限があります。 たとえば、型システムは強力には適用されません。 場合によっては、より厳密な検証が必要になります。 幸いなことに、M には型をサポートする組み込みライブラリが用意されているため、より強力な検証を行うことができます。
開発者は一般的にこれを行うために、型システムについて十分に理解している必要があります。 また、Power Query M 言語仕様では型システムについて十分に説明されていますが、いくつか意外な事が扱われていません。 たとえば、関数インスタンスの検証には、型を比較して互換性を確認する方法が必要です。
M 型システムをより慎重に調べることで、これらの問題の多くは明確にすることができるので、開発者は自分が必要とするソリューションを構築できるようになります。
使用される表記法を理解するには、述語計算および素朴集合論に関する十分な知識が必要です。
準備
(1) B := { true; false }
B は代表的なブール値セットです。
(2) N := { 有効な M 識別子 }
N は M 内で有効なすべての名前のセットです。これは他の場所で定義されます。
(3) P := ⟨B, T⟩
P は関数パラメーターのセットです。 それぞれが省略可能であり、型を持っています。 パラメーター名は無関係です。
(4) Pn := ⋃0≤i≤n ⟨i, Pi⟩
Pn は、n 個の関数パラメーターの順序付けられたすべてのシーケンスのセットです。
(5) P* := ⋃0≤i≤∞ Pi
P* は、長さ 0 からの関数パラメーターのすべての可能なシーケンスのセットです。
(6) F := ⟨B, N, T⟩
F は、すべてのレコード フィールドのセットです。 各フィールドは省略可能であり、名前と型を持っています。
(7) Fn := ∏0≤i≤n F
Fn は、n 個のレコード フィールドのすべてのセットのセットです。
(8) F* := ( ⋃0≤i≤∞ Fi ) ∖ { F | ⟨b1, n1, t1⟩, ⟨b2, n2, t2⟩ ∈ F ⋀ n1 = n }
F* は、(任意の長さの) レコード フィールドのすべてのセットのセットです。ただし、同じ名前を持つフィールドが複数含まれるセットは除きます。
(9) C := ⟨N,T⟩
C は、テーブルにおける列の型のセットです。 各列には、名前と型があります。
(10) Cn ⊂ ⋃0≤i≤n ⟨i, C⟩
Cn は、n 個の列型の順序付けられたすべてのシーケンスのセットです。
(11) C* := ( ⋃0≤i≤∞ Ci ) ∖ { Cm | ⟨a, ⟨n1, t1⟩⟩, ⟨b, ⟨n2, t2⟩⟩ ∈ Cm ⋀ n1 = n2 }
C* は、(任意の長さの) 列の型のすべての組み合わせのセットです。ただし、同じ名前の列が複数存在するものは除きます。
M の型
(12) TF := ⟨P, P*⟩
関数型は、戻り値の型と、0 個以上の関数パラメーターの順序付きリストから成ります。
(13) TL :=〖T〗
リスト型は、中かっこで囲まれた特定の型 ("項目型" と呼ばれます) によって示されます。
メタ言語では中かっこが使用されているため、 このドキュメントでは、〖〗の角かっこが使用されています。
(14) TR := ⟨B, F*⟩
レコード型には、それが "開いている"、0 個以上の順序付けられていないレコード フィールドであるかどうかを示すフラグが含まれます。
(15) TRo := ⟨true, F⟩
(16) TR• := ⟨false, F⟩
TRo および TR• は、それぞれ開いている、および閉じられたレコード型の表記ショートカットです。
(17) TT := C*
テーブル型は、0 個以上の列型の順序付けられたシーケンスであり、名前の競合はありません。
(18) TP := { any; none; null; logical; number; time; date; datetime; datetimezone; duration; text; binary; type; list; record; table; function; anynonnull }
プリミティブ型は、この M キーワード リストからの 1 つです。
(19) TN := { tn, u ∈ T | tn = u+null } = nullable t
"nullable" キーワードを使用することで、任意の型をnull 許容としてさらにマークすることもできます。
(20) T := TF ∪ TL ∪ TR ∪ TT ∪ TP ∪ TN
すべての M 型のセットは、次の 6 つの型セットの和集合です:
関数型、リスト型、レコード型、テーブル型、プリミティブ型、Null 許容型。"
関数
1 つの関数を次のように定義する必要があります: NonNullable : T ← T
この関数では、型が取得され、同等の型が返されます。ただし、null 値に準拠していない場合は例外です。
ID
一部の ID はいくつかの特殊なケースを定義するために必要です。また、上記を明らかにするのに役立つ場合もあります。
(21) nullable any = any
(22) nullable anynonnull = any
(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
型の互換性
他の場所で定義されているように、ある M 型と別の M 型との互換性が成立するための必要十分条件として、最初の型に準拠するすべての値が 2 番目の型にも準拠する必要があります。
ここでは、適合値に依存するのでなく型自体のプロパティに基づいた互換性の関係が定義されています。 このドキュメントで定義されているこの関係は、元のセマンティック定義と完全に等価であると予想されます。
"と互換性がある" の関係 : ≤ : B ← T × T
次のセクションでは、小文字の t は常に、T の要素である M 型を表します。
Φ は F* または C* のサブセットを表します。
(28) t ≤ t
"この関係は再帰的です。 "
(29) ta ≤ tb ∧ tb ≤ tc → ta ≤ tc
"この関係は推移的です。 "
(30) none ≤ t ≤ any
"M 型では、この関係に対して格子が形成されます。 " none "が一番下で、 " any " が一番上になります。 "
(31) ta, tb ∈ TN ∧ ta ≤ ta → NonNullable(ta) ≤ NonNullable(tb)
"2 つの型に互換性がある場合、NonNullable 相当値も互換性があります。 "
(32) null ≤ t ∈ TN
"プリミティブ型の " null " は、すべての null 許容型と互換性があります。 "
(33) t ∉ TN ≤ anynonnull
すべての nonnullable 型は、 anynonnull と互換性があります。
(34) NonNullable(t) ≤ t
"NonNullible 型は、その null 許容相当型と互換性があります。 "
(35) t ∈ TF → t ≤ function
"すべての関数型は、function と互換性があります。 "
(36) t ∈ TL → t ≤ list
"すべてのリスト型は list と互換性があります。 "
(37) t ∈ TR → t ≤ record
"すべてのレコード型は、record と互換性があります。 "
(38) t ∈ TT → t ≤ table
"すべてのテーブル型は table と互換性があります。 "
(39) ta ≤ tb ↔ 〖ta〗≤〖tb〗
"あるリスト型が別のリスト型と互換性を持つのは、項目型に互換性がある場合です。その逆も言えます。 "
(40) ta ∈ TF = ⟨ pa, p* ⟩, tb ∈ TF = ⟨ pb, p* ⟩ ∧ pa ≤ pb → ta ≤ tb
"ある関数型が別の関数型と互換性を持つのは、戻り値の型に互換性があり、パラメーター リストが同一である場合です。 "
(41) ta ∈ TRo, tb ∈ TR• → ta ≰ tb
"開いているレコード型は、閉じられたレコード型と互換性はありません。 "
(42) ta ∈ TR• = ⟨false, Φ⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ tb
"閉じられたレコード型は、それ以外は同である開いているレコード型と互換性があります。 "
(43) ta ∈ TRo = ⟨true, (Φ, ⟨true, n, any⟩)⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ tb ∧ tb ≤ ta
"型が " any "である省略可能なフィールドは、開いている 2 つのレコード型を比較するとき、無視される場合があります。 "
(44) ta ∈ TR = ⟨b, (Φ, ⟨β, n, ua⟩)⟩, tb ∈ TR = ⟨b, (Φ, ⟨β, n, ub⟩)⟩ ∧ ua ≤ ub → ta ≤ tb
"フィールドが 1 つのみが異なる 2 つのレコード型が互換性を持つのは、フィールドの名前とオプションが同じであり、かつ前述フィールドの型に互換性がある場合となります。 "
(45) ta ∈ TR = ⟨b, (Φ, ⟨false, n, u⟩)⟩, tb ∈ TR = ⟨b, (Φ, ⟨true, n, u⟩)⟩ → ta ≤ tb
"省略できないフィールドを持つレコード型は、そのフィールドが省略可能であることを除けば同であるレコード型と互換性があります。 "
(46) ta ∈ TRo = ⟨true, (Φ, ⟨b, n, u⟩)⟩, tb ∈ TRo = ⟨true, Φ⟩ → ta ≤ tb
"開いているレコード型は、フィールドが 1 つ少ない別の開いているレコード型と互換性があります。 "
(47) ta ∈ TT = (Φ, ⟨i, ⟨n, ua⟩⟩), tb ∈ TT = (Φ, ⟨i, ⟨n, ub⟩⟩) ∧ ua ≤ ub → ta ≤ tb
"あるテーブル型は、1 つの列の型が異なることを除けば同じである別のテーブル型と、その列の型に互換性がある場合に互換性があります。 "
REFERENCES
Microsoft Corporation (2015 年 8 月)
Microsoft Power Query for Excel 数式言語仕様 [PDF]
取得元: https://msdn.microsoft.com/library/mt807488.aspx
Microsoft Corporation (n.d.)
Power Query M 関数リファレンス [Web ページ]
取得元: https://msdn.microsoft.com/library/mt779182.aspx