Advertisement
Guest User

Untitled

a guest
Nov 25th, 2015
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.65 KB | None | 0 0
  1. module Uniplate where
  2.  
  3. import Prelude
  4.  
  5. import Data.Maybe (Maybe(), maybe)
  6. import Data.Tuple (Tuple(..))
  7. import Data.Array ((:), uncons)
  8.  
  9. class Uniplate on where
  10. uniplate :: on -> Tuple (Str on) (Str on -> on)
  11.  
  12. descend :: forall on. (Uniplate on) => (on -> on) -> on -> on
  13. descend f x = case uniplate x of
  14. (Tuple current generate) -> generate $ strMap f current
  15.  
  16. transform :: forall on. (Uniplate on) => (on -> on) -> on -> on
  17. transform f = g
  18. where
  19. g x = f (descend g x)
  20.  
  21. rewrite :: forall on. (Uniplate on) => (on -> Maybe on) -> on -> on
  22. rewrite f = transform g
  23. where
  24. g x = maybe x (rewrite f) (f x)
  25.  
  26. data Str a = Zero | One a | Two (Str a) (Str a)
  27.  
  28. instance eqStr :: (Eq a) => Eq (Str a) where
  29. eq Zero Zero = true
  30. eq (One x) (One y) = x == y
  31. eq (Two x1 x2) (Two y1 y2) = x1 == y1 && x2 == y2
  32. eq _ _ = false
  33.  
  34. strMap :: forall a b. (a -> b) -> Str a -> Str b
  35. strMap f x = g x
  36. where
  37. g Zero = Zero
  38. g (One x) = One $ f x
  39. g (Two x y) = Two (g x) (g y)
  40.  
  41. strList :: forall a. Str a -> Array a
  42. strList array = builder (f array)
  43. where
  44. f :: forall f. Str a -> (a -> f a -> f a) -> (f a -> f a -> f a) -> f a -> f a
  45. f Zero _ _ nil = nil
  46. f (One x) cons _ nil = cons x nil
  47. f (Two Zero xs) cons app nil = f xs cons app nil
  48. f (Two (One x) xs) cons app nil = x `cons` f xs cons app nil
  49. f (Two (Two xs ys) zs) cons app nil = (f xs cons app nil) `app` (f ys cons app nil) `app` (f zs cons app nil)
  50.  
  51. builder :: ((a -> Array a -> Array a) -> (Array a -> Array a -> Array a) -> Array a -> Array a) -> Array a
  52. builder g = g (:) (<>) []
  53.  
  54. listStr :: forall a. Array a -> Str a
  55. listStr = maybe Zero (\{ head: x, tail: xs } -> Two (One x) (listStr xs)) <<< uncons
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement