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

use*_*008 1 haskell list

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

我的代码是:

remove :: Eq a => a -> [[a]] -> [[a]]
remove a (x:xs) = filter (not.a) (x:xs)
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误消息:

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

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

Dan*_*her 6

类型filter

filter :: (a -> Bool) -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

所以你传递给的第一个参数filter必须是一个函数,从列表的元素类型到Bool.在

remove :: Eq a => a -> [[a]] -> [[a]]
remove a (x:xs) = filter (not.a) (x:xs)
Run Code Online (Sandbox Code Playgroud)

你说

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

这些暗示在一起

a = [a] -> Bool
Run Code Online (Sandbox Code Playgroud)

但那是一种无限型.

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


Don*_*art 5

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

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

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

这是一个类型错误.

我认为你的意思是过滤所有不相等的元素a,这将是:

remove a xs = filter (/= a) xs 
Run Code Online (Sandbox Code Playgroud)

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

remove a xs = map (filter (/= a)) xs
Run Code Online (Sandbox Code Playgroud)