我试着创建一个函数(我在haskell中是新的),它需要两个列表并返回一个List。列表应该包含第一个列表中的所有元素,它们不在第二个列表中,而且不在第二个列表中,并且不在第一个列表中。
所以:func [3,2,1,4] [2,5,1]
应该返回[3,4,5]
我认为我的代码走向了正确的方向,但其中某处是一个很大的错误。
func :: [Int] -> [Int] -> [Int]
func [] a = a
func a [] = a
func (x:xs) (y:ys) | elem x (y:ys) = filter (/=x) (y:ys)
| otherwise = func ys xs
答案 0 :(得分:0)
假装没有任何关于这个问题领域的经验或者对base
中的函数非常熟悉,我会重新解释你的问题陈述来描述我们想要的操作并告诉你我是如何接近它的:
fun
在两个列表中的结果是:第一个的所有元素 列表,谁不在第二个和所有第二个列表中,谁不是 在第一个。
要在代码中开始表达,请将“是”替换为=
:
func l1 l2 = (elementsOfFirstNotInSecond l1 l2) ++(elementsOfFirstNotInSecond l2 l1)
现在我们需要实现elementsOfFirstNotInSecond
,所以让我们从单词开始:
两个列表中的的尾部
elementsOfFirstNotInSecond
是:如果l1
为空 然后列出空列表,否则如果是l1
的头部(我们会称之为 “x
”)是l2
然后x
成员的成员elementsOfFirstNotInSecond
和l1
的尾的l2
。除此以外 (如果x
中的l2
不是,那么只是elementsOfFirstNotInSecond
l1
和l2
看看你是否可以将其转换为haskell,使用尚未实现的功能(例如,您可能想要使用(isAMemberOf :: Int -> [Int] -> Bool
),并重复该练习。
答案 1 :(得分:0)
输出订单是否重要?
如果没有,您可以使用(\\)
Data.List
Prelude > import Data.List
Prelude Data.List> as = [3,2,1,4]
Prelude Data.List> bs = [2,5,1]
Prelude Data.List> notinSec = as \\ bs
Prelude Data.List> notinFst = bs \\ as
Prelude Data.List> ans = notinSec ++ notinFst
Prelude Data.List> ans
[3,4,5]
答案 2 :(得分:-1)
由于你想要递归并且是haskell的新手,所以解决方案(在你的方向上移动)就像是
func (x:xs) (y:ys) | elem x (y:ys) && (not (elem y (x:xs))) = func xs (filter (/=x) (y:ys))
| (not (elem x (y:ys))) && (elem y (x:xs)) = func (filter (/=y) (x:xs)) ys
| (elem x (y:ys)) && (elem y (x:xs)) = func (filter (/=y) (xs)) (filter (/=x) (ys))
| otherwise = x : y : (func xs ys)
但你可以看到这在你学习道路的后期阶段是多么丑陋和愚蠢。 我建议你选择更简单,更简洁的方法。