1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
import Data.Maybe
import Data.List
class (Ord a) => Joinable a where
key :: a -> String
data Foo = Foo { fooKey :: String, fooVal :: Int }
instance Eq Foo where
x == y = (key x) == (key y)
instance Ord Foo where
compare x y
| x == y = EQ
| (key x) <= (key y) = LT
| otherwise = GT
instance Joinable Foo where
key (Foo k _) = k
data Baz = Baz { bazKey :: String, bazVal :: Int }
instance Eq Baz where
x == y = (key x) == (key y)
instance Ord Baz where
compare x y
| x == y = EQ
| (key x) <= (key y) = LT
| otherwise = GT
instance Joinable Baz where
key (Baz k _) = k
singleMerge :: Maybe Foo -> Maybe Baz -> Maybe Foo
singleMerge (Just f) (Just b) = Just ( f { fooVal = bazVal b } )
merge :: [Foo] -> [Baz] -> [Foo]
merge fs bs = catMaybes $ map (uncurry singleMerge) $ join (sort fs) (sort bs)
join :: (Joinable a, Joinable b) => [a] -> [b] -> [(Maybe a, Maybe b)]
join (x:xs) (y:ys)
| x == y = (Just x, Just y) : join xs ys
| x <= y = (Just x, Nothing) : join xs (y:ys)
| x >= y = (Nothing, Just y) : join (x:xs) ys
|