Skip to content

Instantly share code, notes, and snippets.

@nponeccop
Created March 3, 2017 20:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nponeccop/c20bf5e528be5540b0b696567a950d56 to your computer and use it in GitHub Desktop.
Save nponeccop/c20bf5e528be5540b0b696567a950d56 to your computer and use it in GitHub Desktop.
State monad using Cont
{-# LANGUAGE NoMonomorphismRestriction, Rank2Types #-}
import Control.Monad.Cont
type State s v = s -> (s, v)
set :: a -> State a ()
set x = const (x, ())
get :: State a a
get = \s -> (s, s)
bind :: State a b -> (b -> State a c) -> State a c
bind ma f = \s -> let (s', v) = ma s in f v s'
ret :: a -> State x a
ret a = \s -> (s, a)
run :: s -> State s a -> (s, a)
run s f = f s
foo = get `bind` \s -> set (s + 42) `bind` \_ -> ret "foo"
c x = cont (\fred -> x `bind` fred)
cget :: CState a a
cget = c get
cset :: a -> CState a ()
cset = c . set
type CState s v = forall a . Cont (State s a) v
bar :: CState Int Int
bar = do
x <- cget
cset (x + 42)
cget
crun x f = run x $ runCont f ret
main :: IO ()
main = do
print $ crun 1000 bar
print $ run 1000 foo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment