在GHCi中,执行以下收益:
:t (==) (==) :: Eq a => a -> a -> Bool
要么
:t elem elem :: (Eq a, Foldable t) => a -> t a -> Bool
我对箭头从a到a,然后是a到Bool感到困惑.是因为==或elem是一个curry函数?
elem的类型签名与==非常相似,除了额外的t.是什么t a
在:t elem
意思?
是的,运营商都是咖喱.让我们忽略一秒钟的背景(之前类型的部分=>
).
(==) :: a -> a -> Bool
(->)
联系在右边,所以这意味着:
(==) :: a -> (a -> Bool)
也就是说,它是一个函数,给定一个a
,返回另一个函数,该函数反过来取一个a
并给出一个Bool
.它返回的函数只有在其参数等于第一个时才为真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
必须是支持相等的类型.
至于t
in elem
,这可能有点先进,让你现在完全理解.我会给你一点点.因为上下文
(Eq a, Foldable t) => ...
我们知道t
必须这样做Foldable
.列表是可折叠的,可折叠并不比"有toList
方法"更多.所以你可以读elem
作:
elem :: (Eq a) => a -> [a] -> Bool
通常,当您看到可折叠类型时,只需假装它是一个列表.