警告:非常初學者的問題。如何理解Haskell類型構造函數的有效輸入集?
我目前深陷在Haskell的書我讀代數類型的部分,我已經遇到了下面的例子:
data Id a =
MkId a deriving (Eq, Show)
idInt :: Id Integer
idInt = MkId 10
idIdentity :: Id (a -> a)
idIdentity = MkId $ \x -> x
OK,堅持住。我不完全瞭解idIdentity
示例。書中的解釋是:
這有點奇怪。類型
Id
接受參數,數據 構造函數MkId
接受相應多態的 類型的參數。因此,爲了獲得Id Integer
類型的值,我們需要 將a -> Id a
應用於Integer
值。這將a
類型變量綁定到Integer
,並在類型構造函數中使用(->)
,給我們Id Integer
。我們還可以通過將a
綁定到 類型和術語級別中的多態函數來構建MkId
值,該值是身份 函數。
但是等等。爲什麼只有完全多態的功能?我以前的理解是,a
可以是任何類型。但很顯然,受限的多態類型不起作用:(Num a) => a -> a
不會在這裏工作,並且GHC錯誤表明,只有完全態類型或「合格類型」(不知道那些是什麼)是有效的:
f :: (Num a) => a -> a
f = undefined
idConsPoly :: Id (Num a) => a -> a
idConsPoly = MkId undefined
Illegal polymorphic or qualified type: Num a => a -> a
Perhaps you intended to use ImpredicativeTypes
In the type signature for ‘idIdentity’:
idIdentity :: Id (Num a => a -> a)
編輯:我是一個笨蛋。我在下面的答案中寫下了類型簽名,正如@chepner在他的回答中指出的那樣。這也解決了我在下面的下一句話中的困惑......
回想起來,這種行爲是有道理的,因爲我還沒有爲Id
定義Num
實例。但那麼什麼解釋我能夠在idInt :: Id Integer
中應用Integer
這種類型?
所以在一般情況下,我想我的問題是:什麼是特定的類型構造函數的有效輸入集合?只有完全多態類型?那麼什麼是「合格類型」呢?等...
限定類型是指具有上下文的那些類型,即以'Constraint => ...'開始。約束是「資格」。 –
進入限定類型和多態的一個好的開端是這篇關於排名n類型的博客文章https://ocharles.org.uk/blog/guest-posts/2014-12-18-rank-n-types.html – epsilonhalbe