GHC擴充套件 XRankNTypes是什麼?如何理解forall ?

時間 2021-05-12 05:36:25

1樓:非構造性雨軒菌

補充一下其他答案,舉個例子:

foo :: forall b c. (forall a. a -> a) -> (b, c) -> (b, c)

foo f (b, c) = (f b, f c)然後我們呼叫這個函式:

foo id (1 :: Int, 'c' :: Char)一切都沒問題。但是如果我們將a放到外面,就過不了typecheck,因為Int和Char的鍋。

2樓:Belleve

使用 UTT 的符號的話,並且標出所有的型別引數例項化呼叫的話,forall a. b 可以改寫成這個形式

-> b

其中的 ★ 是所有型別的型別,乙個大類(或者說全集);b 則是乙個可能包含 a 的項,一般是其他型別。在 Haskell 中,呼叫乙個帶有 forall 的函式的時候, 對應的那個引數會由編譯器推理出來填上(而且你還沒辦法手工指定……)

於是你的第乙個例子裡面 theAnswer 的型別是:

theAnswer :: ( -> a -> a) -> Int

theAnswer id = id 42

而第二個例子裡面

theAnswer :: -> (a -> a) -> Int

theAnswer id = id 42

這裡,id 的型別由引數 aTy 決定,但是 aTy 是未知的(它不一定是 Int),所以報錯「Int 無法合演到固化型別變數 a」。

對於第二個問題,既然 forall 本質上就是一種函式型別,那麼自然也需要呼叫它,只不過對於一般的 Rank-1 type,因為傳入的引數都是常量(已知的型別定義),編譯器把對應的函式抽象和呼叫給乾掉了而已。

3樓:baozii

rankntypes 可以將多態函式作為引數

這裡多型的意思是,其引數型別變數沒有出現在外部函式中,你無法根據其他引數和返回值的型別來確定這個作為引數的函式的型別

比如t :: Int -> (forall b . b -> Int) -> Int

t x f = if x == 1 then f 'a' else f 1

rank1 就是函式自己是多型的,但沒有多態函式做引數

rank2 就是有多態函式做引數,但是這個多態函式本身不可以接受多態函式做引數

rank3 就是可以有乙個接受多態函式做引數的多態函式來做引數,但是最裡面那層多態函式不可以接受多態函式做引數

……以此類推……

你第二個的問題出在forall必須作用在作為引數的多態函式上,以顯式說明此函式為多態函式,不然效果如同未開rankntypes

如何評價 GHC 9 0 的 linear type 支援?

應用 tweag關於linear type的部落格。這些部落格從2017年3月到2020年11月。詳細描述了他們做linear type的目的,以及很多很酷的linear type的用法。linear type配套的base庫,裡面有大量基礎的函式,也有很多列子。這個庫目前正在積極的更新中。line...

為什麼 GHC 不預設將所有的 Dict Passing 都 Specialize 掉?

CJex 除了高階型別外,還要考慮分離編譯。GHC 開啟 O 就會自動對 Local 函式進行 Specialize 需要注意的是,如果不寫 module export list,就會預設 export 所有函式。如果乙個被 export 函式在本地 module 中有可以 Specialize 的...

顯示卡擴充套件塢的存在必要?

給我吧 顯示卡擴充套件塢還是很有必要的,對你來說或許沒有,但不代表別人沒需求。台式電腦的確實最划算 效能最好的,但畢竟體積擺在那裡,你出差的時候一定不會帶台式電腦吧,筆記本最重要的一點就是輕便性,出差的時候帶膝上型電腦,在家接顯示卡擴充套件塢玩遊戲,完美的組合,總比在買一台玩遊戲的電腦划算吧。外表小...