Guest User

Untitled

a guest
Oct 22nd, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.54 KB | None | 0 0
  1. {-# LANGUAGE RankNTypes, ScopedTypeVariables, DeriveTraversable, PatternSynonyms, UndecidableInstances, FlexibleInstances, ViewPatterns, InstanceSigs #-}
  2.  
  3. module Fix where
  4.  
  5. import Control.Monad (ap, join, (<=<))
  6. import Control.Applicative (empty, Alternative, (<|>))
  7. import Control.Arrow
  8. import Data.Functor.Compose
  9.  
  10. -- Free f a = Mu x. a + f x
  11. -- Cofree f a = Nu x. a * f x
  12. -- Mu < Fix < Nu
  13.  
  14. newtype Fix f = Fix (f (Fix f))
  15.  
  16. unfix :: Fix f -> f (Fix f)
  17. unfix (Fix f) = f
  18.  
  19. cata :: Functor f => (f b -> b) -> Fix f -> b
  20. cata alg = alg . fmap (cata alg) . unfix
  21.  
  22. cataM :: (Traversable t, Monad f) => (t b -> f b) -> Fix t -> f b
  23. cataM alg = alg <=< traverse (cataM' alg) . unfix
  24.  
  25. ana :: Functor f => (a -> f a) -> a -> Fix f
  26. ana coalg = Fix . fmap (ana coalg) . coalg
  27.  
  28. anaM :: (Monad m, Traversable f) => (a -> m (f a)) -> a -> m (Fix f)
  29. anaM f = fmap Fix . traverse (anaM f) <=< f
  30.  
  31. futu :: Functor f => (a -> f (Free f a)) -> a -> Fix f
  32. futu coalg t = ana go (Free(Fix(ReturnF t))) where
  33. go (Free(Fix(ReturnF a))) = coalg a
  34. go (Free(Fix(BindF fa))) = fmap Free fa
  35.  
  36. futuM :: (Traversable f, Monad m) => (a -> m (f (Free f a))) -> a -> m (Fix f)
  37. futuM coalg t = anaM go (Free(Fix(ReturnF t))) where
  38. go (Free(Fix(ReturnF a))) = coalg a
  39. go (Free(Fix(BindF fa))) = return (fmap Free fa)
  40.  
  41. histo :: Functor f => (f (Cofree f a) -> a) -> Fix f -> a
  42. histo h = unfix >>> fmap worker >>> h where
  43. worker t = Cofree(Fix(CoBindF (histo h t) (fmap (uncofree . worker) (unfix t))))
  44.  
  45. histoM :: (Traversable f, Monad m) => (m (f (Cofree f a)) -> a) -> Fix f -> m a
  46. histoM f = ?
  47.  
  48. hylo :: Functor f => (f b -> b) -> (a -> f a) -> a -> b
  49. hylo f g = h where h = f . fmap h . g
  50.  
  51. hyloM :: (Traversable t, Monad m) => (t b -> m b) -> (a -> m (t a)) -> a -> m b
  52. hyloM f g = f <=< traverse (hyloM f g) <=< g
  53.  
  54. data CofreeF f a r = CoBindF a (f r) deriving (Functor, Foldable, Traversable)
  55.  
  56. data FreeF f a r = ReturnF a | BindF (f r) deriving (Functor, Foldable, Traversable)
  57.  
  58. newtype Free f a = Free(Fix(FreeF f a))
  59.  
  60. newtype Cofree f a = Cofree(Fix(CofreeF f a))
  61.  
  62. unfree :: Free f a -> Fix (FreeF f a)
  63. unfree (Free v) = v
  64.  
  65. uncofree :: Cofree f a -> Fix (CofreeF f a)
  66. uncofree (Cofree v) = v
  67.  
  68. extract :: Cofree f a -> a
  69. extract (Cofree(Fix(CoBindF a _))) = a
  70.  
  71. instance Functor f => Functor (Cofree f) where
  72. fmap :: (a -> b) -> Cofree f a -> Cofree f b
  73. fmap f = Cofree . go . uncofree where
  74. go (Fix (CoBindF a as)) = Fix (CoBindF (f a) (fmap go as))
  75.  
  76. instance Alternative f => Monad (Cofree f) where
  77. return a = Cofree (Fix (CoBindF a empty))
  78. (Cofree(Fix(CoBindF a m))) >>= f = case f a of
  79. (Cofree(Fix(CoBindF b n))) -> Cofree(Fix(CoBindF b (fmap uncofree ((fmap Cofree n) <|> (fmap ((>>= f) . Cofree) m)))))
  80.  
  81. instance Alternative f => Applicative(Cofree f) where
  82. pure = return
  83. (<*>) = ap
  84.  
  85. liftF :: Functor f => f a -> Free f a
  86. liftF c = Free (Fix (BindF $ fmap (unfree . Free . Fix . ReturnF) c))
  87.  
  88. instance Functor f => Functor (Free f) where
  89. fmap :: (a -> b) -> Free f a -> Free f b
  90. fmap f = Free . cata go . unfree where
  91. go (ReturnF a) = Fix (ReturnF (f a))
  92. go (BindF a) = Fix (BindF a)
  93.  
  94. instance Functor f => Applicative(Free f) where
  95. pure = return
  96. (<*>) = ap
  97.  
  98. instance Functor f => Monad (Free f) where
  99. return a = Free (Fix (ReturnF a))
  100. x >>= f = Free $ go $ unfree x where
  101. go (Fix (ReturnF a)) = unfree $ f a
  102. go (Fix (BindF a)) = Fix . BindF $ fmap go a
  103.  
  104. retract :: (Monad f, Traversable f) => Free f b -> f b
  105. retract = cataM alg . unfree where
  106. alg (ReturnF a) = return a
  107. alg (BindF as) = as
Add Comment
Please, Sign In to add comment