Foldr到工会名单

时间:2013-04-19 00:54:49

标签: haskell

考虑以下myUnion函数,必须按如下方式开始:

myUnion xs ys = foldr ....

我要做的是使用foldr创建一个新列表,其中包含xsys的所有元素,不会有任何重复。我必须首先复制xs中不在ys内的所有元素,然后复制此检查后剩余的所有ys元素。

我一直试图解决这个问题已经有一段时间没有任何成功了。我自然会尝试将xsys分解为x:resty:rest2并使用前奏函数elem来检查某个元素是否在列表中但是,不得不使用foldr表明可能有一种更简单的方法可以解决这个问题,并且考虑到必须从foldr开始,我很难想出解决这个问题的方法。

我很感激有关如何解决这个问题的任何建议。

非常感谢提前。

1 个答案:

答案 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
相关问题