请为以下错误提供帮助。基本上对于给定的项目列表,我想创建一个函数来检查项目是否在该列表中。为了做到这一点,我将列表转换为一个集合,然后围绕该集合创建一个闭包。
toAccept :: Ord a => [a] -> (a -> Bool)
toAccept xs =
let xset = Set.fromList xs in
let
-- accept:: Ord a => a -> Bool
accept x = Set.member xset x in
accept
我得到的是
Could not deduce (a ~ Set.Set (Set.Set a))
from the context (Ord a)
bound by the type signature for
toAccept :: Ord a => [a] -> a -> Bool
at Tokens.hs:6:13-39
`a' is a rigid type variable bound by
the type signature for toAccept :: Ord a => [a] -> a -> Bool
at Tokens.hs:6:13
Expected type: a -> Bool
Actual type: Set.Set (Set.Set a) -> Bool
In the expression: accept
In the expression: let accept x = Set.member xset x in accept
In the expression:
let xset = Set.fromList xs in
let accept x = Set.member xset x in accept
我做错了什么?
答案 0 :(得分:2)
你的论点已经失败
let accept x = Set.member x xset in accept
作为一项规则,在haskell函数中,数据结构是最后一个,因为这使得它适合无点样式。有关详情,请参阅here。
可能更好的写作方式是
toAccept' :: Ord a => [a] -> a -> Bool
toAccept' = flip Set.member . Set.fromList
这里我们利用了Haskell的currying功能,因为[a] -> a -> Bool
与[a] -> (a -> Bool)
相同。我们实际上可以编写我们的函数,好像它接收两个参数并且不接受一个并返回一个函数,因为在Haskell中,这些选项是相同的。