考虑以下myUnion
函数,必须按如下方式开始:
myUnion xs ys = foldr ....
我要做的是使用foldr
创建一个新列表,其中包含xs
和ys
的所有元素,不会有任何重复。我必须首先复制xs
中不在ys
内的所有元素,然后复制此检查后剩余的所有ys
元素。
我一直试图解决这个问题已经有一段时间没有任何成功了。我自然会尝试将xs
或ys
分解为x:rest
和y:rest2
并使用前奏函数elem
来检查某个元素是否在列表中但是,不得不使用foldr
表明可能有一种更简单的方法可以解决这个问题,并且考虑到必须从foldr开始,我很难想出解决这个问题的方法。
我很感激有关如何解决这个问题的任何建议。
非常感谢提前。
答案 0 :(得分:2)
请注意,使用用于设置的列表并不是一个好主意:
myUnion xs ys = Data.List.foldr Data.Set.insert Data.Set.empty (xs ++ ys)
如果你有uniq值的排序列表,你可能想要使用展开:
myUnions xs0 ys0 = unfoldr walk (xs0, ys0) where
walk ([], []) = Nothing
walk ([], (y:ys')) = Just (y, ([], ys'))
walk ((x:xs'), []) = Just (x, (xs', []))
walk (xs@(x:xs'), ys@(y:ys')) | x < y = Just (x, (xs', ys))
| x > y = Just (y, (xs, ys'))
| otherwise = Just (x, (xs', ys'))
但如果你还坚持:
myUnion xs ys = foldr myInsert [] (xs++ys) where
myInsert x zs = if x `elem` zs then zs else (x:zs)
-- this one expects that both lists have uniq items
-- and checks only elements from xs for presence in ys
myUnion xs ys = foldr myInsert ys xs where
myInsert x zs = if x `elem` ys then zs else (x:zs)
-- but this should be written differently I guess
myUnion xs ys = filter (`notElem` ys) xs ++ ys