Haskell 为 == 和 elem 键入签名

Haskell type signature for == and elem

在 GHCi 中,执行以下产量:

:t (==) 

(==) :: Eq a => a -> a -> Bool

:t elem

elem :: (Eq a, Foldable t) => a -> t a -> Bool

我对从 a 到 a,然后从 a 到 Bool 的箭头感到困惑。 是因为 == 还是 elem 是柯里化函数?

elem 的类型签名与 == 非常相似,除了附加的 t。 :t elem中的t a是什么意思?

是的,运算符被柯里化了。让我们暂时忽略上下文(=> 之前的类型部分)。

(==) :: a -> a -> Bool

(->) 关联到右边,所以这意味着:

(==) :: a -> (a -> Bool)

也就是说,它是一个函数,给定一个 a,returns 另一个函数,它又接受一个 a 并给出一个 Bool。它 returns 这个函数只有当它的参数等于第一个 a.

时才为真

(我们将设置 NoMonomorphismRestriction,否则它会无缘无故地变得更加混乱)

ghci> :set -XNoMonomorphismRestriction
ghci> let f = (==) 1
ghci> f 1
True
ghci> f 2
False
-- or just
ghci> (==) 1 2
False

(=>) 之前的部分对类型进行了限制。 Eq a表示a必须是支持相等的类型。

至于 elem 中的 t,这可能有点高级,您现在无法完全理解。我给你一点。因为语境

(Eq a, Foldable t) => ...

我们知道 t 必须是 Foldable。列表是可折叠的,可折叠并不意味着比 "has a toList method" 多多少。所以你可以读 elem 为:

elem :: (Eq a) => a -> [a] -> Bool

一般来说,当您看到可折叠类型时,就把它当作一个列表。