我正在尝试使用haskell删除列表中项目的所有实例。我得到一个我不太懂的错误。任何人都可以帮助我,让我知道我做的正确吗?
deleteAllInstances :: (a, [l]) => a -> [l] -> [l]
deleteAllInstances (a, []) = []
deleteAllInstances (i, (x:xs))
| i == x = tail
| otherwise = x ++ tail
where tail = deleteAllInstances i xs
答案 0 :(得分:9)
首先,类型签名格式不正确。
deleteAllInstances :: (a, [l]) => a -> [l] -> [l]
类型签名的格式为
name :: (Constraints) => type
其中Constraints
涉及类型类,例如(Ord a, Show a)
。在这种情况下,函数使用(==)
,因此必须有Eq a
形式的约束。
然后函数定义与类型部分不匹配,你将它定义为一对作为参数,而类型签名则另有说明(你的定义是不合理的,类型是curry)。
deleteAllInstances (a, []) = []
deleteAllInstances (i, (x:xs))
| i == x = tail
| otherwise = x ++ tail
where tail = deleteAllInstances i xs
然后使用(++)
将元素粘贴到列表的前面,但(++)
连接两个列表,此处需要(:)
。
定义函数的最简单方法是使用filter
deleteAllInstances :: Eq a => a -> [a] -> [a]
deleteAllInstances a xs = filter (/= a) xs
但是如果你想自己做明确的递归,
deleteAllInstances :: Eq a => a -> [a] -> [a]
deleteAllInstances a (x:xs)
| a == x = rest
| otherwise = x : rest
where
rest = deleteAllInstances a xs
deleteAllInstances _ _ = []
答案 1 :(得分:3)
我不确定您在(a, [l])
之前使用=>
尝试做什么,但我认为没有必要。通常保留语法来指定a和l应该满足的类型。
此外,您的函数有两个参数a
和[l]
,正如您稍后在函数定义中指定的那样。但是,您的函数实现只需要一个参数,一个元组。正如我之前提到的,元组只用于指定参数应该是什么类型,并且不能进行模式匹配。
deleteAllInstances :: a -> [l] -> [l]
deleteAllInstances a [] = []
deleteAllInstances i (x:xs)
| i == x = rest
| otherwise = x : rest
where rest = deleteAllInstances i xs
如果您想使用filter
编写,可以随时使用以下代码
deleteAllInstances :: a -> [a] -> [a]
deleteAllInstances a = filter (/=a)
答案 2 :(得分:3)
我实际上发现列表理解对于这样的问题是一个非常直观的表示法:
deleteAllInstances :: Eq a => a -> [a] -> [a]
deleteAllInstances a list = [x | x <- list, x /= a]