Last active
December 19, 2017 03:54
-
-
Save gallais/4c59b949c743c0a85cab55dcb73aaf7c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DeriveFunctor #-} | |
module MonadTree where | |
import Control.Monad | |
import Control.Monad.Fix | |
newtype Tree m a = Tree { runTree :: m (Node m a) } | |
deriving (Functor) | |
data Node m a = Node | |
{ nodeValue :: a | |
, nodeChildren :: [Tree m a] | |
} deriving (Functor) | |
valueM :: Functor m => Tree m a -> m a | |
valueM = fmap nodeValue . runTree | |
childrenM :: Functor m => Tree m a -> m [Tree m a] | |
childrenM = fmap nodeChildren . runTree | |
joinTree :: Monad m => m (Tree m a) -> Tree m a | |
joinTree = Tree . join . fmap runTree | |
instance Monad m => Applicative (Tree m) where | |
pure a = Tree $ pure $ Node a [] | |
(<*>) = ap | |
instance Monad m => Monad (Tree m) where | |
return = pure | |
m >>= k = | |
Tree $ do | |
Node x xs <- runTree m | |
Node y ys <- runTree (k x) | |
pure . Node y $ | |
fmap (>>= k) xs ++ ys | |
instance Monad m => MonadFix (Tree m) where | |
mfix f = Tree $ do | |
shape <- fix $ (pure . f =<<) . (valueM =<<) | |
node <- runTree shape | |
let value = nodeValue node | |
let trees = nodeChildren node | |
let children = zipWith (\ k _ -> mfix (joinTree . fmap (!! k) . childrenM . f)) [0..] trees | |
return $ Node value children |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is it okay if I adapt this for use in
Data.Tree
? I believe in that simpler context it looks like this: