如何修复“发生检查:无法构造无限类型”错误?

时间:2012-05-03 20:42:04

标签: list haskell

我正在尝试编写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'

错误消息的含义是什么,以及如何更改第二行以使其有效?

2 个答案:

答案 0 :(得分: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的类型为a,列表的类型为[[a]],即列表元素类型为[a]
  2. not . afilter的第一个参数,类型为[a] -> Bool
  3. 这些暗示着

    a = [a] -> Bool
    

    但这是一种无限型。

    如果filter (not . (a `elem`))适用于外部列表,则可能表示类似filter (a `notElem`)或等效filter的内容,如果要删除,则map (filter (/= a))来自每个包含列表的元素。

答案 1 :(得分:5)

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

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

not的类型为:: Bool -> Bool,因此a必须为Bool类型。但是你已经说不了,它的类型为Eq t => t

这是一个类型错误。

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

remove a xs = filter (/= a) xs 

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

remove a xs = map (filter (/= a)) xs