1

我正在尝试编写一个remove函数,以便用户可以键入remove 'd' ["abc", "dc", "ad"]并获取输出["abc", "c", "a"]

我的代码是:

remove :: Eq a => a -> [[a]] -> [[a]]
remove a (x:xs) = filter (not.a) (x:xs)

但我收到以下错误消息:

Occurs check: cannot construct the infinite type: a = [a] -> Bool
   When generalising the type(s) for `remove'

错误消息是什么意思,如何更改第二行以使其正常工作?

4

2 回答 2

6

的类型filter

filter :: (a -> Bool) -> [a] -> [a]

因此,您传递给的第一个参数filter必须是从列表的元素类型到Bool. 在

remove :: Eq a => a -> [[a]] -> [[a]]
remove a (x:xs) = filter (not.a) (x:xs)

你说

  1. a有 type a,并且列表有 type [[a]],即列表元素类型是[a],并且
  2. not . a,第一个参数filter,具有类型[a] -> Bool

总之,这些意味着

a = [a] -> Bool

但这是一个无限的类型。

如果要在外部列表上工作,或者如果您想从每个包含的列表中删除一个元素,您可能意味着类似filter (not . (a `elem`))或等效filter (a `notElem`)的意思。filtermap (filter (/= a))

于 2012-05-03T20:46:32.343 回答
5

您声明参数a是任何支持相等的类型。

但是您随后在布尔表达式中使用它:not . a.

的类型not:: Bool -> Bool,所以a必须是类型Bool。但是你已经说过不,它是 type Eq t => t

所以这是一个类型错误。

我认为您的意思是过滤所有不等于的元素,a即:

remove a xs = filter (/= a) xs 

但是,您的输入也是一个嵌套列表,因此您必须将过滤器映射到内部元素:

remove a xs = map (filter (/= a)) xs
于 2012-05-03T20:46:08.947 回答