基本用法
啟用 GADTs
擴充套件後,除常規資料宣告外,還可以宣告廣義代數資料型別,如下所示:
-hs langCopydata DataType a where
Constr1 :: Int -> a -> Foo a -> DataType a
Constr2 :: Show a => a -> DataType a
Constr3 :: DataType Int
GADT 宣告明確列出了資料型別具有的所有建構函式的型別。與常規資料型別宣告不同,建構函式的型別可以是任何 N-ary(包括 nullary)函式,最終會導致應用於某些引數的資料型別。
在這種情況下,我們宣稱 DataType
型別有三個建構函式:Constr1
,Constr2
和 Constr3
。
Constr1
建構函式與使用常規資料宣告宣告的建構函式沒有什麼不同:data DataType a = Constr1 Int a (Foo a) | ...
但是 Constr2
要求 a
有一個 Show
的例項,因此在使用建構函式時,例項需要存在。另一方面,當模式匹配時,a
是 Show
的一個例項的事實進入範圍,所以你可以寫:
-hs langCopyfoo::DataType a -> String
foo val = case val of
Constr2 x -> show x
...
請注意,Show a
約束不會出現在函式的型別中,並且僅在 ->
右側的程式碼中可見。
Constr3
的型別為 DataType Int
,這意味著只要 DataType a
的值為 Constr3
,就知道 a ~ Int
。此資訊也可以通過模式匹配來恢復。