RankNTypes
想象一下以下情況:
foo::Show a => (a -> String) -> String -> Int -> IO ()
foo show' string int = do
putStrLn (show' string)
putStrLn (show' int)
在這裡,我們希望傳入一個將值轉換為 String 的函式,將該函式應用於字串引數和 int 引數,並將它們列印出來。在我看來,沒有理由這會失敗! 我們有一個函式可以處理我們傳入的兩種型別的引數。
不幸的是,這不會打字檢查! GHC 根據函式體中的第一次出現推斷出 a
型別。也就是說,只要我們點選:
putStrLn (show' string)
GHC 將推斷 show' :: String -> String
,因為 string
是 String
。在嘗試使用時,它會繼續爆炸。
RankNTypes
允許你改為按如下方式編寫型別簽名,對所有滿足 show'
型別的函式進行量化:
foo :: (forall a. Show a => (a -> String)) -> String -> Int -> IO ()
這是 2 級多型:我們斷言 show'
函式必須適用於我們函式中的所有 a
s,並且之前的實現現在可以工作。
RankNTypes
擴充套件允許在型別簽名中任意巢狀 forall ...
塊。換句話說,它允許秩 N 多型性。