共用方式為


Power Query M 公式語言中的類型

Power Query M 公式語言是實用且易懂的資料混搭語言。 不過有一些限制。 例如不會嚴格實施類型系統。 在某些情況下,必須要有較嚴格的驗證。 幸好,M 提供支援類型的內建程式庫,以進行更嚴格的驗證。

開發人員應該要通盤了解類型系統,才能以任何一般的方式來執行此操作。 而且,雖然 Power Query M 語言規格詳細說明類型系統,但還是有一些令人意想不到的地方。 例如,若要驗證函式執行個體,需要某種方式來比較類型的相容性。

藉由深入探索 M 類型系統,可以明確了解其中的許多問題,而開發人員也就能夠建立所需的解決方案。

述詞演算和樸素集合論的知識,應足以了解所使用的標記法。

準備工作

(1) B := { ; 錯誤 }
B 是一般的布林值集合

(2) N := { 有效 M 個識別碼 }
N 是 M 中所有有效名稱的集合。這會在其他地方定義。

(3) P := ⟨BT
P 是函式參數的集合。 每一個都可能是選擇性,並具有類型。 參數名稱並不相關。

(4) Pn := ⋃0≤i≤niPi
Pn 是 n 函式參數的所有排序序列集合。

(5) P* := ⋃0≤i≤∞Pi
P* 是所有可能的函式參數序列集合,從長度 0 開始。

(6) F := ⟨BNT
F 是所有記錄欄位的集合。 每個欄位都可能是選擇性,並具有名稱和類型。

(7) Fn := ∏0≤i≤nF
Fn 是所有 n 記錄欄位集合的集合。

(8) F* := ( ⋃0≤i≤∞Fi ) ∖ { F | ⟨b1n1t1⟩, ⟨b2n2t2⟩ ∈ Fn 1 = n2 }
F* 是記錄欄位所有集合 (任何長度) 的集合,但其中有超過一個欄位名稱相同的集合除外。

(9) C := ⟨N,T
C 是資料表的資料行類型集合。 每個資料行各有名稱和類型。

(10) Cn⋃0≤i≤niC
Cn 是 n 資料行類型的所有排序序列集合。

(11) C* := ( ⋃0≤i≤∞Ci ) ∖ { Cm | ⟨a, ⟨n1t1⟩⟩, ⟨b, ⟨n2t2⟩⟩ ∈ Cmn 1 = n2 }
C* 是資料行類型所有組合 (任何長度) 的集合,但其中超過一個資料行名稱相同的除外。

M 類型

(12) TF := ⟨PP*
函式類型包含傳回型別,以及零或多個函式參數的排序清單。

(13) TL :=〖T
清單類型以大括號括住的特定類型 (稱為「項目類型」) 來表示。 由於元語言中使用了大括號, 因此在本文件中會使用〖 〗 括弧。

(14) TR= B⟨F*
記錄類型有一個會指出其是否為「已開啟」的旗標,以及零或多個未排序的記錄欄位。

(15) TRo := ⟨真,F

(16) TR := ⟨假,F
TRo and TR 分別是已開啟和已關閉記錄類型的標記捷徑。

(17) TT : = C*
資料表類型是零或多個資料行類型的排序次序,其中沒有名稱衝突。

(18) TP := { any;none;null;logical;number;time;datetime;datetime;duration;text;binary;type;list;record;table;function;anynonnull }
基本類型是此 M 關鍵字清單中的其中之一。

(19) TN := { tn, u ∈ T | t n = u+null } = 可空 t
任何類型都可以使用 "nullable" 關鍵字來另外標記為可為 Null。

(20) T := TFTLTRTT ∪TPT N
所有 M 類型集合都是這六種類型集合的聯合:
函式類型、清單類型、記錄類型、資料表類型、基本類型及可為 Null 的類型。

函式

有一個必須定義的函式:NonNullable : TT
此函式會採用類型並傳回對等的類型,但不符合 Null 值。

身分識別

某些特殊案例必須要有某些身分識別才能定義,也可能有助於說明上述情況。

(21) 可歸零,任意 = 任意
(22) 可為零 任意非零 = 任意
(23) 可空零 = 空
(24) 可為零 無 = 無
(25) 可空 可 空 tT = 可空 t
(26) NonNullable(nullable t ∈T) = NonNullablet
(27) NonNullable(any) = anynonnull

類型相容性

如在其他位置所定義,只有在符合第一個類型的所有值也符合第二個類型時,M 類型才會與另一個 M 類型相容。

這裡定義的相容性關聯不相依於符合的值,且以類型本身的屬性為基礎。 在本文件中定義的這種關聯性,可預期會完全等同於原始語義定義。

「相容於」關聯性:≤ : BT × T
在下一節中,小寫 t 一律代表 M 類型,也就是 T 的元素。

A Φ 將代表 F*C* 的子集。

(28) TT
這種關係是反射性的。

(29) TaTbTbT CT ≤ T C
此關係是傳遞的。

(30) 沒有≤
M 類型會透過此關聯性來形成辨識格;none 是底部,而 any 是頂端。

(31) tatbTNtat aNonNullableta) ≤ NonNullabletb
如果兩種類型相容,則 NonNullable 對等項目也會相容。

(32) 空≤ t ∈TN
基本類型 null 與所有可為 Null 的類型相容。

(33) tTN ≤任非零
所有的不可為 Null 類型都與 anynonnull 相容。

(34) 不可歸(t) ≤ t
NonNullible 類型與可為 Null 的對等項目相容。

(35) tTFt ≤ 函式
所有函式類型都與函式相容。

(36) tTLt ≤ 清單
所有清單類型都與清單相容。

(37) tTRt ≤ 記錄
所有記錄類型都與記錄相容。

(38) tTTt ≤ 資料表
所有資料表類型都與資料表相容。

(39) tatb ↔ 〖ta〗≤〖tb
如果項目類型相容,則清單類型會與另一個清單類型相容,反之亦然。

(40) taTF = ⟨ pap* ⟩, tbTF = ⟨ pbp* ⟩ ∧ papb →tat b
如果傳回型別相容,且參數清單相同,則函式類型會與另一個函式類型相容。

(41) TaTRotbTRtat b
已開啟記錄類型一律不會與已關閉記錄類型相容。

(42) taTR = ⟨Φ⟩, tbTRo = ⟨為真Φ⟩ → tatb
已關閉記錄類型與另一個相同的已開啟記錄類型相容。

(43) taTRo = ⟨,(Φ, ⟨truen, any⟩)⟩, t bTRo = ⟨Φ⟩ → ta ≤tbtbta
在比較兩個已開啟記錄類型時,可能會忽略具有 any 類型的選擇性欄位。

(44) taTR = ⟨b, (Φ, ⟨βnua⟩)⟩, tb ∈TR = ⟨b, (Φ, ⟨βnub⟩)⟩ ∧ uaubtat b
如果欄位的名稱和選用性相同,且所述欄位的類型相容,則只有一個欄位不同的兩種記錄類型會相容。

(45) taTR = ⟨b, (Φ, ⟨falsenu⟩)⟩, tbTR = ⟨b, (Φ, ⟨truenu⟩)⟩ → tatb
具有非選擇性欄位的記錄類型,與該欄位為選擇性的相同記錄類型相容。

(46) taTRo = ⟨,(Φ, ⟨bnu⟩)⟩, tbTRo = ⟨Φ⟩ → tat b
已開啟記錄類型與另一個具有較少欄位的已開啟記錄類型相容。

(47) taT = (Φ, ⟨i, ⟨nua⟩⟩), tbT =Φ, ⟨i, ⟨nub⟩⟩) ∧ uaubtat b
資料表類型與第二種資料表類型 (相同但具有一個不同類型的資料行,並在該資料行相容時) 相容。