Skip to content

fumieval/monad-skeleton

Repository files navigation

monad-skeleton

Build Status Hackage

This package provides Skeleton, an operational monad (i.e. free monad that does not require the Functor implementation). The internal encoding gives O(1) bind and monadic reflection.

Skeleton promotes unit instructions to a monad. It is isomorphic to MonadView (Skeleton t):

data MonadView t m x where
  Return :: a -> MonadView t m a
  (:>>=) :: !(t a) -> (a -> m b) -> MonadView t m b

boned :: MonadView t (Skeleton t) a -> Skeleton t a
debone :: Skeleton t a -> MonadView t (Skeleton t) a

GADTs are handy to define instructions:

data Interaction x where
  Get :: Interaction String
  Put :: String -> Interaction ()

echo :: Skeleton Interaction ()
echo = bone Get >>= bone . Put

Use debone to interpret a computation.

interpret :: Skeleton Interaction a -> IO a
interpret m = case debone m of
  Return a -> return a
  Get :>>= k -> getLine >>= interpret . k
  Put s :>>= k -> putStrLn s >>= interpret . k