删除列表中的所有实例
我试图使用haskell删除列表中的项目的所有实例。我收到一个我不太明白的错误。任何人都可以帮助我,让我知道如果我做正确的事情?删除列表中的所有实例
deleteAllInstances :: (a, [l]) => a -> [l] -> [l]
deleteAllInstances (a, []) = []
deleteAllInstances (i, (x:xs))
| i == x = tail
| otherwise = x ++ tail
where tail = deleteAllInstances i xs
首先,类型签名的格式不正确。
deleteAllInstances :: (a, [l]) => a -> [l] -> [l]
A型签名的形式
name :: (Constraints) => type
其中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
然后使用(++)
一个元素胶水列表的前面,但(++)
连接两个列表,你需要(:)
这里。
定义函数是使用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 _ _ = []
如果我想让它也可以在字符串上工作而不仅仅是数字 – cclerville 2012-04-11 22:16:39
这里没有提到数字,它适用于所有类型的'Eq'实例,包括'String','[String]'等等。它具有最普通的类型,因此它适用于可能适用的所有内容。 (你可以通过一个参数'(a - > a - > Bool)'去掉'Eq'约束,该参数说明哪些值应该被认为是'相等的';'Eq'类提供的函数类似于隐式参数) – 2012-04-11 22:25:02
你说得对。谢谢! :) – cclerville 2012-04-11 23:21:50
我不知道你想与(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)
其实我觉得列表理解是一个非常直观的符号表示这样的问题:
deleteAllInstances :: Eq a => a -> [a] -> [a]
deleteAllInstances a list = [x | x <- list, x /= a]
它不是更快 - 都是'O(n)'。甚至像'filter'这样的链接多个函数仍然是'O(n)',因为_Fusion_,例如'过滤器f。地图f'。过滤器f''仍然是'O(n)'。 – 2013-06-16 08:45:34
复杂性显然是相同的,但据我了解ghc,编译后的代码会更快,因为列表解析被解析为纯粹的递归,因此您将调用保存到过滤器。它可能取决于约束的复杂性。 – thrau 2013-06-16 14:06:46
实际上,列表解析只是一个替代的符号语法,因此,如果一个'/ = a'然后返回一个'else []',你的理解首先解析为'list >> = \ a' - >。在那之后,优化器确实做了平移递归的转换,但是它对所生成的函数执行了这个操作,并且它会对任何受_Fusion_影响的其他函数执行。 'filter'和'map'也受到融合,这就是为什么生成的编译器代码应该与你的相同。你可以试验__ghc-core__ util,你会惊讶于优化器实际上可以做什么。 – 2013-06-16 14:24:45
你会得到哪个错误? – 2012-04-11 21:27:40