如果這個問題很愚蠢,請原諒我。
在閱讀有關 Haskell 種類的資訊時,我注意到一個主題:
*
* -> *
* -> * -> *
我的印象是 Haskell 中的種類最終歸結為有多少個星號。你可能會說一個型別的種類實際上只是在它變成 * 之前你需要應用到它的型別的數量。換句話說,您可以計算除最后一個之外的所有 *,并通過整數定義型別的種類。說 0、1、2 等。
這是我的問題:
這是對 Haskell 型別系統的正確觀察嗎?或者它是否允許除 * 之外的其他東西去你通常看到 * 的地方?例如:
* -> a -> *
例如,我想有人可能想要這樣做來約束型別變數以具有型別類的實體。
Functor a, Applicative b => * -> a -> b -> *
那是一回事嗎?
uj5u.com熱心網友回復:
kind 語言的最基本形式只包含*(或者Type在更現代的 Haskell 中;我懷疑我們最終會遠離*)和->.
但是,使用該語言可以構建的東西比僅通過“計算*s 的數量”所能表達的要多。這不僅僅是數量*或->問題,而是它們如何嵌套。例如* -> * -> *,一種使用兩個型別引數來生成型別(* -> *) -> *的東西,但是那種使用單個引數來生成型別的東西,其中引數本身必須是使用型別引數來生成型別的東西。data ThreeStars a b = Cons a b用 kind創建一個型別建構式* -> * -> *,而用 kinddata AlsoThreeStars f = AlsoCons (f Integer)創建一個型別建構式(* -> *) -> *。
有幾種語言擴展可以為這種語言添加更多功能。
PolyKinds添加型別變數的作業方式與型別變數的作業方式完全相同。現在我們可以有像forall k. (* -> k) -> k.
ConstraintKinds使約束(=>in 型別簽名左側的東西,如Eq a)成為一種新型別的普通型別級物體:Constraint. 而不是剩下的=>特殊用途語法與語言的其余部分完全脫節,現在可以接受的是 kind Constraint。類Eq成為具有 kind 的型別建構式* -> Constraint;你把它應用到一個型別上,比如Eq Bool生成一個Constraint. 優點是現在我們可以使用所有語言特性來操作型別級物體來操作約束(包括PolyKinds!)。
DataKinds添加了創建包含新型別級別事物的新用戶定義型別的能力,就像在 vanilla Haskell 中我們可以創建包含新術語級別事物的新用戶定義型別一樣。(完全相同的方式;DataKinds實際作業的方式是它允許您data正常使用宣告,然后您可以在型別或種類級別使用生成的型別建構式)
還有一些用于未裝箱/未提升型別的型別,它們不能與“普通”Haskell 型別混合,因為它們具有不同的記憶體布局;它們不能包含 thunk 來實作惰性求值,因此運行時必須知道永遠不要嘗試將它們作為代碼指標“輸入”,或尋找額外的標頭位等。它們需要在種類級別保持分開,所以那種普通型別的變數*不能用這些未提升/未裝箱的型別實體化(這將允許您將這些需要特殊處理的型別傳遞給不知道提供特殊處理的通用代碼)。我隱約知道這些東西,但實際上從未使用過它,所以我不會再添加了,所以我不會出錯。(任何知道他們在說什么的人都可以在這里寫一個簡短的摘要段落,請隨時編輯答案)
可能還有一些我忘記了。但可以肯定的是,這種語言比 OP 想象的僅具有基本的 Haskell 功能更豐富,一旦你打開一些(相當廣泛使用的)擴展,它就會有更多的東西。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/427258.html
標籤:哈斯克尔
上一篇:普通函式和型別類函式有什么區別?
