Written in this handy do-notation, this seems pretty clear to me. But I can't seem to get the de-sugared version using >>=
to work which is worrisom. Could someone re-write these in expanded notation please?
Not nested
stack1 :: StateT Int Identity ( Int, Int )
stack1 = do
a <- get
put ( a + 1 )
b <- get
return ( a, b )
runstack1 :: ( Int, Int )
runstack1 = evalState stack1 11
Nested
stack3 :: StateT Int ( StateT String ( StateT String Identity ) ) ( Int, String, String )
stack3 = do
modify (+10)
lift $ modify ( ++ " world" )
lift . lift $ modify ( ++ " word" )
a <- get
b <- lift get
c <- lift . lift $ get
return ( a, b, c )
runStack3 :: ( Int, String, String )
runStack3 = runIdentity $ evalStateT ( evalStateT ( evalStateT runStack3 1 ) "hello" ) "harro"
Additionally, by comparing at the signature of runStack1 and runStack3 I can see why runIdentity
is needed, but could someone explain the internals of why this is, since both stack1 and stack3 are wrapping Identity constructor?