从列表中删除所有实例

ccl*_*lle 3 recursion haskell 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
Run Code Online (Sandbox Code Playgroud)

Dan*_*her 9

首先,类型签名是错误的.

deleteAllInstances :: (a, [l]) =>  a -> [l] -> [l]
Run Code Online (Sandbox Code Playgroud)

类型签名具有表单

name :: (Constraints) => type
Run Code Online (Sandbox Code Playgroud)

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

然后函数定义与类型部分不匹配,您将其定义为将一对作为参数,而类型签名则另有说明(您的定义不合理,类型为curried).

deleteAllInstances (a, []) = []
deleteAllInstances (i, (x:xs))
    | i == x = tail
    | otherwise = x ++ tail
    where tail = deleteAllInstances i xs
Run Code Online (Sandbox Code Playgroud)

然后你用(++)一个元素粘贴到列表的前面,但是(++)你需要连接两个列表(:).

定义函数的最简单方法是使用 filter

deleteAllInstances :: Eq a => a -> [a] -> [a]
deleteAllInstances a xs = filter (/= a) xs
Run Code Online (Sandbox Code Playgroud)

但如果你想自己做明确的递归,

deleteAllInstances :: Eq a => a -> [a] -> [a]
deleteAllInstances a (x:xs)
    | a == x    = rest
    | otherwise = x : rest
      where
        rest = deleteAllInstances a xs
deleteAllInstances _ _ = []
Run Code Online (Sandbox Code Playgroud)

  • 这里没有提到数字,它适用于作为`Eq`实例的每一种类型,包括`String`,`[String]`等等.它具有它可以具有的最通用的类​​型,因此它适用于它可能工作的一切.(您可以通过使用参数`(a - > a - > Bool)来消除`Eq`约束,该参数说明哪些值应该被视为'相等';`Eq`类提供该函数作为隐式参数.) (5认同)