Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.66 KB | None | 0 0
  1. {-# LANGUAGE MultiParamTypeClasses, GADTs, DeriveFunctor, ScopedTypeVariables #-}
  2.  
  3. --------------------------------------------------------------------------------
  4. -- Left join implemented for lists
  5.  
  6. class HOrd a b where
  7. hcmp :: a -> b -> Ordering
  8.  
  9. instance Ord a => HOrd (a, b) (a, c) where
  10. hcmp (x, _) (y, _) = compare x y
  11.  
  12. leftJoin :: HOrd a b => [a] -> [b] -> [(a, Maybe b)]
  13. leftJoin [] _ = []
  14. leftJoin (x:xs) ys = (x, y'):leftJoin xs ys' where
  15. (y', ys') = findLEQ ys
  16. findLEQ [] = (Nothing, [])
  17. findLEQ (y:ys)
  18. | hcmp x y == GT = findLEQ ys
  19. | hcmp x y == LT = (Nothing, y:ys)
  20. | hcmp x y == EQ = (Just y, y:ys)
  21.  
  22. leftJoinWith :: HOrd a b => (a -> Maybe b -> c) -> [a] -> [b] -> [c]
  23. leftJoinWith f xs ys = uncurry f <$> leftJoin xs ys
  24.  
  25. --------------------------------------------------------------------------------
  26. -- "Unfold" based streams
  27.  
  28. data ListF r a = NilF | ConsF a r deriving(Functor)
  29. type Step s a = s -> ListF s a
  30.  
  31. data Stream a where
  32. Stream :: Step s a -> s -> Stream a
  33.  
  34. instance Functor Stream where
  35. fmap g (Stream f s0) = Stream (\s -> g <$> f s) s0
  36.  
  37. list :: [a] -> Stream a
  38. list = Stream f where
  39. f [] = NilF
  40. f (x:xs) = ConsF x xs
  41.  
  42. stream :: Stream a -> [a]
  43. stream (Stream f s0) = go s0 where
  44. go s = case f s of
  45. NilF -> []
  46. ConsF x s' -> x:go s'
  47.  
  48. --------------------------------------------------------------------------------
  49. -- Left join implemented for streams
  50.  
  51. leftJoinStep :: HOrd a b => Step l a -> Step r b -> Step (l, r) (a, Maybe b)
  52. leftJoinStep lstep rstep = \(l, r0) -> case lstep l of
  53. NilF -> NilF
  54. ConsF x l' ->
  55. let
  56. (y', r') = findLEQ r0
  57. findLEQ r = case rstep r of
  58. NilF -> (Nothing, r)
  59. ConsF y r'
  60. | hcmp x y == GT -> findLEQ r'
  61. | hcmp x y == LT -> (Nothing, r)
  62. | hcmp x y == EQ -> (Just y, r)
  63. in
  64. ConsF (x, y') (l', r')
  65.  
  66. leftJoinS :: HOrd a b => Stream a -> Stream b -> Stream (a, Maybe b)
  67. leftJoinS (Stream lf l0) (Stream rf r0) = Stream (leftJoinStep lf rf) (l0, r0)
  68.  
  69. leftJoinWith' :: HOrd a b => (a -> Maybe b -> c) -> [a] -> [b] -> [c]
  70. leftJoinWith' f xs ys = stream (uncurry f <$> leftJoinS (list xs) (list ys))
  71.  
  72. --------------------------------------------------------------------------------
  73. -- Expected output:
  74. -- ["Aa","Bb","B'b","C","Dd"]
  75.  
  76. main :: IO ()
  77. main = do print $ leftJoinWith combine xs ys
  78. print $ leftJoinWith combine xs ys
  79. where
  80. xs :: [(Int, String)]
  81. ys :: [(Int, Char)]
  82.  
  83. xs = [(0,"A"), (1,"B"), (1,"B'"), (2,"C"), (3,"D") ]
  84. ys = [(0,'a'), (1,'b'), (3,'d'), (4,'e')]
  85.  
  86. combine (_, l) Nothing = l
  87. combine (_, l) (Just (_, r)) = l ++ [r]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement