3

我正在尝试使用haskell删除列表中某个项目的所有实例。我收到一个我不太明白的错误。谁能帮助我,让我知道我是否做对了?

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

3 回答 3

9

首先,类型签名格式错误。

deleteAllInstances :: (a, [l]) =>  a -> [l] -> [l]

类型签名具有以下形式

name :: (Constraints) => type

其中Constraints涉及类型类,例如(Ord a, Show a). 在这种情况下,该函数使用(==),因此必须有一个形式的约束Eq a

然后函数定义与类型部分不匹配,您将其定义为将一对作为参数,而类型签名则另有说明(您的定义是非柯里化的,类型是柯里化的)。

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 _ _ = []
于 2012-04-11T21:32:25.657 回答
4

我不确定您要对(a, [l])before做=>什么,但我认为没有必要。语法通常保留用于指定 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)
于 2012-04-11T21:31:10.893 回答
3

实际上,我发现列表推导是解决此类问题的一种非常直观的表示法:

deleteAllInstances :: Eq a => a -> [a] -> [a]
deleteAllInstances a list = [x | x <- list, x /= a]
于 2013-06-16T03:17:04.067 回答