我想定義以下函式:
f a = f
此函式接受一個引數并忽略該引數回傳自身。只是在 ghci 中這樣寫會給我以下型別錯誤:
? Couldn't match expected type ‘t’ with actual type ‘p0 -> t’
‘t’ is a rigid type variable bound by
the inferred type of f :: t
如果函式將使用此引數,則有可能(如在此停止示例中):
halt = halt
或使用一個引數
halt x = halt x
是否有可能命名這種型別或編譯以前的程式?當然,這不是出于任何特定原因,只是試圖理解型別理論,特別是在 haskell 中,更好 - 你永遠無法應用這個函式來產生特定的結果。
uj5u.com熱心網友回復:
好吧,你可以“幾乎”擁有它。
正如已經提到的,你不能有一個無限型別a -> b -> c -> ...,因為 Haskell 型別必須是有限的。
但是,我們可以定義一個遞回newtype,它在“道德上”是上面的無限型別,并使用它:
newtype F = F { unF :: forall a. a -> F }
f :: F
f = F (\x -> f)
用更簡單的術語來說,這構造了一個F滿足的型別F ~= forall a . a -> F,它是產生所需“無限”型別的方程。
請注意使用forall a允許x擁有任何型別。(幾乎)函式f本質上是一個“饑餓”函式,它會吃掉任何型別的任何引數并回傳自己。
但是,這種方法有一個缺點。要實際應用f,我們需要解開建構式。這導致代碼像
g :: F
g = unF (unF f True) "hello"
這比g = f True "hello".
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/528540.html
標籤:哈斯克尔函数式编程类型论
下一篇:訪問sum型別變體中的公共欄位
