我正在尝试编写一个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)
错误消息的含义是什么,以及如何更改第二行以使其有效?
类型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)
你说
a有类型a,列表有类型[[a]],即列表元素类型是[a],和not . a,第一个参数filter,有类型[a] -> Bool.这些暗示在一起
a = [a] -> Bool
Run Code Online (Sandbox Code Playgroud)
但那是一种无限型.
如果要在外部列表上工作,或者如果要从每个包含的列表中删除元素,则可能意味着类似filter (not . (a `elem`))或类似的东西.filter (a `notElem`)filtermap (filter (/= a))
您声明该参数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)
| 归档时间: |
|
| 查看次数: |
434 次 |
| 最近记录: |