Monad m where (>>=) :: forall a b. m a -> (a -> m b) -> m b (>>) :: forall a b. m a -> m b -> m b m >> k = m >>= \_ -> k {-# INLINE (>>) #-} return :: a -> m a return = pure fail :: String -> m a fail s = errorWithoutStackTrace s scalaz/Monad.scala
= Pure a | Free (f (Free f a)) instance Functor f => Monad (Free f) where return = pure {-# INLINE return #-} Pure a >>= f = f a Free m >>= f = Free ((>>= f) <$> m) scalaz/Free.scala
f (Number n expr) = Number n $ f expr fmap f (Add expr) = Add $ f expr fmap f (Sub expr) = Sub $ f expr fmap f (Mul expr) = Mul $ f expr fmap _ End = End
b = Free (RPNExpr a) b liftF :: (Functor f) => f r -> Free f r liftF = Free . fmap Pure num :: a -> RPN a () num n = liftF $ Number n () add :: RPN a () add = liftF $ Add () sub :: RPN a () sub = liftF $ Sub () mul :: RPN a () mul = liftF $ Mul () end :: RPN a b end = liftF End
String (RPN a ()) parse = foldM rpn (Pure ()) . reverse . words where rpn e "+" = Right . Free $ Add e rpn e "-" = Right . Free $ Sub e rpn e "*" = Right . Free $ Mul e rpn _ "." = Right $ Free End rpn e n = case reads n of [(v,_)] -> Right . Free $ Number v e _ -> Left "invalid input"