Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monadic versions #5

Open
xgrommx opened this issue Aug 6, 2017 · 3 comments
Open

Monadic versions #5

xgrommx opened this issue Aug 6, 2017 · 3 comments

Comments

@xgrommx
Copy link
Contributor

xgrommx commented Aug 6, 2017

Hello @vmchale Here my haskell version of monadic RS

type AlgebraM m f a = f a -> m a
type ParaAlgebraM m t a = Base t (t, a) -> m a
type CataM m t a = AlgebraM m (Base t) a -> t -> m a

paraM
  :: (Recursive t, Traversable (Base t), Monad m) =>
     ParaAlgebraM m t a -> t -> m a
paraM alg = alg <=< traverse(liftA2 (liftA2 (,)) return (paraM alg)) . project

apoM :: (Monad m, Traversable (Base t), Corecursive t) => (a -> m (Base t (Either t a))) -> a -> m t
apoM coalg = (return . embed) <=< traverse(either return (apoM coalg)) <=< coalg

anaM
  :: (Monad m, Traversable (Base t), Corecursive t)
  => (a -> m (Base t a)) -> a -> m t
anaM f = fmap embed . traverse (anaM f) <=< f

futuM :: (Corecursive t, Traversable (Base t), Monad m)
      => (a -> m (Base t (Free (Base t) a)))
      -> a
      -> m t
futuM coalg = anaM go . Pure
  where
    go (Pure a)  = coalg a
    go (Free fa) = return fa

hyloM
  :: (Monad m, Traversable t)
  => (t b -> m b) -> (a -> m (t a)) -> a -> m b
hyloM alg coalg = h
  where h = alg <=< traverse h <=< coalg

cataM
  :: (Monad f, Traversable (Base a), Recursive a) => CataM f a b
cataM f = (>>= f) . (traverse (cataM f)) . project

also interesting examples =)

dropWhileM' :: Monad m => (a -> m Bool) -> [a] -> m [a]
dropWhileM' p = para psi where
  psi = \case
    Nil -> return []
    Cons x (xs, ys) -> do
      flg <- p x
      case () of
        _ | flg -> ys
        _ -> return $ x:xs

takeWhileM' :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
takeWhileM' p = cata psi where
  psi = \case
    Nil -> return []
    Cons x xs -> do
      flg <- p x
      if flg then (x:) <$> xs else return []

insertByM' :: (Monad m) => (a -> a -> m Bool) -> a -> [a] -> m [a]
insertByM' cmp x = paraM psi where
 psi = \case
   Nil -> return [x]
   Cons y (xs, ys) -> (\flg -> return $ if flg then x:xs else y:ys) =<< cmp x y

sortByM :: (Monad m) => (a -> a -> m Bool) -> [a] -> m [a]
sortByM cmp = cataM psi where
  psi = \case
    Nil -> return []
    Cons x xs -> insertByM cmp x xs

filterM' :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
filterM' p = cataM psi where
  psi = \case
    Nil -> return []
    Cons x xs -> do
      flg <- p x
      return $ if flg then x:xs else xs

-- And nice examples for it

permutations' = sortByM (\_ _ -> [False, True])
subsequences' = filterM' (const [False, True])
inits' = takeWhileM' (const [False, True])
tails' = dropWhileM' (const [False, True])

Also metamorphism

meta :: (Recursive t, Corecursive c) => (a -> Base c a) -> (b -> a) -> (Base t b -> b) -> t -> c
meta f e g = ana f . e . cata g

ex1 :: [Int] -> [Int]
ex1 = meta f id g where
  g Nil = 0
  g (Cons x xs) = x + xs
  f n | n <= 0 = Nil
      | otherwise = Cons n (n - 1)

I have dyna and other implementation

@vmchale
Copy link
Owner

vmchale commented Aug 9, 2017

Sounds good! I'll get to adding these when I'm less busy with work. Thanks for the issue!

@xgrommx
Copy link
Contributor Author

xgrommx commented Aug 10, 2017

@vmchale Also about zygoM I know about (maybe wrong) signature, but I cannot to implement it. So I think it should be

zygoM
  :: (Monad m, Traversable (Base a), Recursive a) =>
     (Base a b -> m b) -> (Base a (b, c) -> m c) -> a -> m c
zygoM = undefined

I tried to implement it in haskell but maybe I don't know how it should be correct

@xgrommx
Copy link
Contributor Author

xgrommx commented Aug 10, 2017

lotz84 added a commit to lotz84/recursion-algorithms that referenced this issue May 7, 2020
cutsea110 added a commit to cutsea110/aop that referenced this issue May 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants