从列表中删除所有实例

时间:2012-04-11 21:25:25

标签: haskell recursion functional-programming

我正在尝试使用haskell删除列表中项目的所有实例。我得到一个我不太懂的错误。任何人都可以帮助我,让我知道我做的正确吗?

deleteAllInstances :: (a, [l]) =>  a -> [l] -> [l]
deleteAllInstances (a, []) = []
deleteAllInstances (i, (x:xs))
    | i == x = tail
    | otherwise = x ++ tail
    where tail = deleteAllInstances i xs

3 个答案:

答案 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]