With ordered sets (lists) and Ord key
key = fst
fullOuterJoin xs [] = map (\x -> (Just x, Nothing)) xs
fullOuterJoin [] ys = map (\y -> (Nothing, Just y)) ys
fullOuterJoin xss@(x:xs) yss@(y:ys) =
if key x == key y
then (Just x, Just y): fullOuterJoin xs ys
else
if key x < key y
then (Just x, Nothing): fullOuterJoin xs yss
else (Nothing, Just y): fullOuterJoin xss ys
(complexity is O(n+m)
but if you must to sort then is O(n log n + m log m)
)
example
setA = [(1, "hello"), (2, "world")]
setB = [(1, "bar"), (3, "foo")]
*Main> fullOuterJoin setA setB
[(Just (1,"hello"),Just (1,"bar")),(Just (2,"world"),Nothing),(Nothing,Just (3, "foo"))]
(obviously with sort
support
fullOuterJoin' xs ys = fullOuterJoin (sort xs) (sort ys)
As @Franky say, you can avoid if
, for example
fullOuterJoin xs [] = [(Just x, Nothing) | x <- xs]
fullOuterJoin [] ys = [(Nothing, Just y) | y <- ys]
fullOuterJoin xss@(x:xs) yss@(y:ys) =
case (compare `on` key) x y of
EQ -> (Just x, Just y): fullOuterJoin xs ys
LT -> (Just x, Nothing): fullOuterJoin xs yss
GT -> (Nothing, Just y): fullOuterJoin xss ys