Skip to content

Instantly share code, notes, and snippets.

@err0r500
Created September 4, 2018 13:30
Show Gist options
  • Save err0r500/953aaa694b6c134e481b4b7fec12be91 to your computer and use it in GitHub Desktop.
Save err0r500/953aaa694b6c134e481b4b7fec12be91 to your computer and use it in GitHub Desktop.
monad stacking example
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
module Main where
import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer
type Response = String
stack :: (MonadState Int m, MonadWriter [String] m, MonadError String m) => m Response
stack = do
r <- get
tell ["Hello!"]
put (r + 1)
r <- get
tell ["Value: " ++ show r]
-- throwError "Error!"
return ("this is the response" :: Response)
type A = (ExceptT String (WriterT [String] (State Int))) String
runStackWithA = runState (runWriterT (runExceptT (stack :: A)))
type B = (StateT Int (WriterT [String] (Either String))) String
runStackWithB x = runWriterT (runStateT (stack :: B) x)
type C = (WriterT [String] (StateT Int (Either String))) String
runStackWithC = runStateT (runWriterT (stack :: C))
main :: IO ()
main = do
print ("A => " ++ show (runStackWithA 0))
print ("B => " ++ show (runStackWithB 1))
print ("C => " ++ show (runStackWithC 2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment