Haskell MTL: How to exit the monad and get the value within it? - haskell

I know how to use functions from each monad inside a do block. But once i'm finished how do I run the computation and get the result?
run :: (MonadError Error m, MonadState State m) => m Int -> Int
run = ???

The whole point of mtl is that you don't specify your concrete monad transformer stack - you just specify that it has to handle errors and hold state.
However, once you actually want to run this action, you do need to tie yourself down to a particular monad transformer stack. That stack will inform how you can "run" your monadic action. In your case, it looks like you probably want to go with ExcepT Error (State State):
action :: (MonadError Error m, MonadState State m) => m Int
action = undefined
runAction :: State -> -- initial state
Either Error Int -- account for possibility of error
runAction initialState = evalState (runExceptT action) initialState
Note that this isn't the only choice of a concrete stack you could have made. In fact, you could even swap the order of the State and Except and choose StateT State (Either Error) as your monad!
runAction :: State -> -- initial state
Either Error Int -- account for possibility of error
runAction initialState = evalState action initialState
The fact that mtl says nothing about the order of monads in your stack is one of its shortcomings (and one of the reasons why some people prefer to just stick with transformers).

Related

How to understand `MonadUnliftIO`'s requirement of "no stateful monads"?

I've looked over https://www.fpcomplete.com/blog/2017/06/tale-of-two-brackets, though skimming some parts, and I still don't quite understand the core issue "StateT is bad, IO is OK", other than vaguely getting the sense that Haskell allows one to write bad StateT monads (or in the ultimate example in the article, MonadBaseControl instead of StateT, I think).
In the haddocks, the following law must be satisfied:
askUnliftIO >>= (\u -> liftIO (unliftIO u m)) = m
So this appears to be saying that state is not mutated in the monad m when using askUnliftIO. But to my mind, in IO, the entire world can be the state. I could be reading and writing to a text file on disk, for instance.
To quote another article by Michael,
False purity We say WriterT and StateT are pure, and technically they
are. But let's be honest: if you have an application which is entirely
living within a StateT, you're not getting the benefits of restrained
mutation that you want from pure code. May as well call a spade a
spade, and accept that you have a mutable variable.
This makes me think this is indeed the case: with IO we are being honest, with StateT, we are not being honest about mutability ... but that seems another issue than what the law above is trying to show; after all, MonadUnliftIO is assuming IO. I'm having trouble understanding conceptually how IO is more restrictive than something else.
Update 1
After sleeping (some), I am still confused but am gradually getting less so as the day wears on. I worked out the law proof for IO. I realized the presence of id in the README. In particular,
instance MonadUnliftIO IO where
askUnliftIO = return (UnliftIO id)
So askUnliftIO would appear to return an IO (IO a) on an UnliftIO m.
Prelude> fooIO = print 5
Prelude> :t fooIO
fooIO :: IO ()
Prelude> let barIO :: IO(IO ()); barIO = return fooIO
Prelude> :t barIO
barIO :: IO (IO ())
Back to the law, it really appears to be saying that state is not mutated in the monad m when doing a round trip on the transformed monad (askUnliftIO), where the round trip is unLiftIO -> liftIO.
Resuming the example above, barIO :: IO (), so if we do barIO >>= (u -> liftIO (unliftIO u m)), then u :: IO () and unliftIO u == IO (), then liftIO (IO ()) == IO (). **So since everything has basically been applications of id under the hood, we can see that no state was changed, even though we are using IO. Crucially, I think, what is important is that the value in a is never run, nor is any other state modified, as a result of using askUnliftIO. If it did, then like in the case of randomIO :: IO a, we would not be able to get the same value had we not run askUnliftIO on it. (Verification attempt 1 below)
But, it still seems like we could do the same for other Monads, even if they do maintain state. But I also see how, for some monads, we may not be able to do so. Thinking of a contrived example: each time we access the value of type a contained in the stateful monad, some internal state is changed.
Verification attempt 1
> fooIO >> askUnliftIO
5
> fooIOunlift = fooIO >> askUnliftIO
> :t fooIOunlift
fooIOunlift :: IO (UnliftIO IO)
> fooIOunlift
5
Good so far, but confused about why the following occurs:
> fooIOunlift >>= (\u -> unliftIO u)
<interactive>:50:24: error:
* Couldn't match expected type `IO b'
with actual type `IO a0 -> IO a0'
* Probable cause: `unliftIO' is applied to too few arguments
In the expression: unliftIO u
In the second argument of `(>>=)', namely `(\ u -> unliftIO u)'
In the expression: fooIOunlift >>= (\ u -> unliftIO u)
* Relevant bindings include
it :: IO b (bound at <interactive>:50:1)
"StateT is bad, IO is OK"
That's not really the point of the article. The idea is that MonadBaseControl permits some confusing (and often undesirable) behaviors with stateful monad transformers in the presence of concurrency and exceptions.
finally :: StateT s IO a -> StateT s IO a -> StateT s IO a is a great example. If you use the "StateT is attaching a mutable variable of type s onto a monad m" metaphor, then you might expect that the finalizer action gets access to the most recent s value when an exception was thrown.
forkState :: StateT s IO a -> StateT s IO ThreadId is another one. You might expect that the state modifications from the input would be reflected in the original thread.
lol :: StateT Int IO [ThreadId]
lol = do
for [1..10] $ \i -> do
forkState $ modify (+i)
You might expect that lol could be rewritten (modulo performance) as modify (+ sum [1..10]). But that's not right. The implementation of forkState just passes the initial state to the forked thread, and then can never retrieve any state modifications. The easy/common understanding of StateT fails you here.
Instead, you have to adopt a more nuanced view of StateT s m a as "a transformer that provides a thread-local immutable variable of type s which is implicitly threaded through a computation, and it is possible to replace that local variable with a new value of the same type for future steps of the computation." (more or less a verbose english retelling of the s -> m (a, s)) With this understanding, the behavior of finally becomes a bit more clear: it's a local variable, so it does not survive exceptions. Likewise, forkState becomes more clear: it's a thread-local variable, so obviously a change to a different thread won't affect any others.
This is sometimes what you want. But it's usually not how people write code IRL and it often confuses people.
For a long time, the default choice in the ecosystem to do this "lowering" operation was MonadBaseControl, and this had a bunch of downsides: hella confusing types, difficult to implement instances, impossible to derive instances, sometimes confusing behavior. Not a great situation.
MonadUnliftIO restricts things to a simpler set of monad transformers, and is able to provide relatively simple types, derivable instances, and always predictable behavior. The cost is that ExceptT, StateT, etc transformers can't use it.
The underlying principle is: by restricting what is possible, we make it easier to understand what might happen. MonadBaseControl is extremely powerful and general, and quite difficult to use and confusing as a result. MonadUnliftIO is less powerful and general, but it's much easier to use.
So this appears to be saying that state is not mutated in the monad m when using askUnliftIO.
This isn't true - the law is stating that unliftIO shouldn't do anything with the monad transformer aside from lowering it into IO. Here's something that breaks that law:
newtype WithInt a = WithInt (ReaderT Int IO a)
deriving newtype (Functor, Applicative, Monad, MonadIO, MonadReader Int)
instance MonadUnliftIO WithInt where
askUnliftIO = pure (UnliftIO (\(WithInt readerAction) -> runReaderT 0 readerAction))
Let's verify that this breaks the law given: askUnliftIO >>= (\u -> liftIO (unliftIO u m)) = m.
test :: WithInt Int
test = do
int <- ask
print int
pure int
checkLaw :: WithInt ()
checkLaw = do
first <- test
second <- askUnliftIO >>= (\u -> liftIO (unliftIO u test))
when (first /= second) $
putStrLn "Law violation!!!"
The value returned by test and the askUnliftIO ... lowering/lifting are different, so the law is broken. Furthermore, the observed effects are different, which isn't great either.

How to print the result of a State Monad in Haskell?

Is it possible to print the result of a state monad in Haskell?
I'm trying to understand state monads and in a book I have been following supplies the code below for creating a state monad, but I am struggling with this topic as I am unable to view the process visually i.e. see the end result.
newtype State s a = State { runState :: s -> (a,s)}
instance Monad (State s) where
return x = State $ \s -> (x,s)
(State h) >>= f = State $ \s -> let (a, newState) = h s
(State g) = f a
in g newState
It is generally not possible to print functions in a meaningful way. If the domain of the function is small, you can import Data.Universe.Instances.Show from the universe-reverse-instances package to get a Show instance that prints a lookup table that is semantically equivalent to the function. With that module imported, you could simply add deriving Show to your newtype declaration to be able to print State actions over small state spaces.
The code you've supplied defines the kind of thing State s a is. And it also says that State s is a monad - that is, the kind of thing State s is conforms to the Monad typeclass/interface. This means you can bind one State s computation to another (as long as the type s is the same in each).
So your situation is analogous to that of someone who has defined the kind of thing that a Map is, and has also written code that says a Map conforms to such and such interfaces, but who doesn't have any maps, and hasn't yet run any computation with them. There's nothing to print then.
I take it you want to see the result of evaluating or executing your state actions, but you have not defined any actual state actions yet, nor have you called runState (or evalState or execState) on them. Don't forget you also need to supply an initial state to run the computation.
So maybe start by letting s and a be some particular types. E.g. let s be Int and let a be Int. Now you could go write some fns, e.g. f :: Int -> (Int, Int), and g :: Int -> (Int, Int). Maybe one function decrements the state, returning the new state and value, and another function increments the state, returning the new state and value. Then you could make a State Int Int out of f by wrapping it in the State constructor. And you could use >>= to chain as many state actions together as you like. Finally, you can use runState on this, to get the resulting value and resulting state, as long as you also supply an initial state (e.g. 0).
If it's just the result you want, and if you're just debugging:
import Debug.Trace
import Control.Monad.Trans.State
action :: State [Int] ()
action = do
put [0]
modify (1:)
modify (2:)
get >>= traceShowM
modify (3:)
modify (4:)
get >>= traceShowM

Lift to fix the *inside* of a monad transformer stack

Suppose I have an IO Int wrapped in a StateT MyState, then I have a value of State MyState Int which I want to use in the stacked monad. How do I lift it in this inner sense? I already know to use lift or liftIO if I get something compatible with the inside that I just need to lift to the outside monad, but now I have the opposite problem: the value is already in the outer monad but not the inner one.
For instance:
checkSame :: State MyState a -> IO a -> StateT MyState IO Bool
checkSame sim real = do
rres <- liftIO real
sres <- ??? sim
return $ rres == sres
Do I have to 'get' the state, shove it through runState by hand and box it all up again, or is there some generic way to do this?
BTW, that sim parameter is a whole bunch of stateful functions that have nothing to do with IO, so I'm a bit reluctant to make them all return StateT MyState IO a if I can avoid it.
You have two options:
Find a monad morphism. This is often a matter of finding the right library; in this case hoist and generalize together should get you where you need to go.
Make your State action more polymorphic. This is the commonly used one, and the recommended one; it amounts to pre-applying the morphism from part 1, but has a lot of machinery put in place already in the mtl library to make it easy. The idea here is that if you write your State action just in terms of get, put, and modify, then instead of the type State s a, you can give it the type:
MonadState s m => m a
Then later, at the call site, you can choose whatever monad is appropriate for this, including both State s a and StateT s IO a. Moreover, since it specializes to the type State s a, you can be sure it doesn't do any IO or anything like that that State s a itself couldn't do, so you get the same behavioral guarantees.

How do you reason about the order of execution of functions in a monadT stack?

General theme: While I find the idea of stacking monads together is very appealing, I am having a lot of trouble picturing how the code is executed, and what are the appropriate orders to run the layers. Below is one example of a stack: Writer, State, State, and Error, in no particular order ( or is there? ).
-----------------------
-- Utility Functions --
-----------------------
type Memory = Map String Int
type Counter = Int
type Log = String
tick :: (MonadState Counter m) => m ()
tick = modify (+1)
record :: (MonadWriter Log m) => Log -> m ()
record msg = tell $ msg ++ "; "
------------------
-- MonadT Stack --
------------------
mStack :: ( MonadTrans t, MonadState Memory m, MonadState Counter (t m), MonadError ErrMsg (t m), MonadWriter Log (t m) ) => t m Int
mStack = do
tick
m <- lift get
let x = fromJust ( M.lookup "x" m ) in x
record "accessed memory"
case True of
True -> return 100
False -> throwError "false"
Please note in mStack, whether an error is thrown or not has nothing to do with any other part of the function.
Now ideally I want the output to look like this:
( Right 100, 1, "accessed memory", fromList [...])
or in general:
( output of errorT, output of stateT Counter, output of writerT, output of StateT Memory )
But I cannot get it to work. Specifically, I tried running the stack as if Error is on the outermost layer:
mem1 = M.fromList [("x",10),("y",5)]
runIdentity $ runWriterT (runStateT (runStateT (runErrorT mStack ) 0 ) mem1 ) ""
But am getting this error message:
Couldn't match type `Int' with `Map [Char] Int'
The above instance aside, in general, when I am calling:
runMonadT_1 ( runMonadT_2 expr param2 ) param1,
are the functions relating to monadT_2 run first, then that output is piped into the functions relating to monadT_1 ? So in other words, as imperative as the code looks in the above function mStack, is the order of execution entirely dependent upon the order in which the monadT are run ( aside from any rigidness in structure introduced by lift ) ?
You would have gotten a more informative type error if you had tried to type your computation using an explicit monad transformer stack:
mStack :: ErrorT String (StateT (Map String Int) (StateT Int Writer)) Int
Had you done that, ghc would have caught the type error earlier. The reason is that you use the following two commands within mStack at the top-most level:
modify (+1) -- i.e. from `tick`
...
yourMap <- lift get
If you were to give this an explicit stack, then you'd catch the mistake: both modify and lift get are going to target the first StateT layer they encounter, which happens to be the same StateT layer.
modify begins from the ErrorT layer and proceeds downward until it hits the outer StateT layer, and concludes that the outer StateT must be using an Int state. get begins from the outer StateT layer, notices that it's already in a StateT layer and ignores the inner StateT layer entirely, so it concludes that the outer StateT layer must be storing a Map.
ghc then says "What gives? This layer can't be storing both an Int and a Map!", which explains the type error you got. However, because you used type classes instead of a concrete monad transformer stack, there was no way that ghc could know that this was a type error in waiting until you specified a concrete stack.
The solution is simple: just add another lift to your get and it will now target the inner StateT layer like you intended.
I personally prefer to avoid mtl classes entirely and always work with a concrete monad transformer stack using the transformers library alone. It's more verbose because you have to be precise about which layer you want using lift, but it causes fewer headaches down the road.

Confusion over the State Monad code on "Learn you a Haskell"

I am trying to get a grasp on Haskell using the online book Learn you a Haskell for great Good.
I have, to my knowledge, been able to understand Monads so far until I hit the chapter introducing the State Monad.
However, the code presented and claimed to be the Monad implementation of the State type (I have not been able to locate it in Hoogle) seems too much for me to handle.
To begin with, I do not understand the logic behind it i.e why it should work and how the author considered this technique.( maybe relevant articles or white-papers can be suggested?)
At line 4, it is suggested that function f takes 1 parameter.
However a few lines down we are presented with pop, which takes no parameters!
To extend on point 1, what is the author trying to accomplish using a function to represent the State.
Any help in understanding what is going on is greatly appreciated.
Edit
To whom it may concern,
The answers below cover my question thoroughly.
One thing I would like to add though:
After reading an article suggested below, I found the answer to my second point above:
All that time I assumed that the pop function would be used like :
stuff >>= pop since in the bind type the second parameter is the function, whereas the correct usage is this pop >>= stuff , which I realized after reading again how do-notation translates to plain bind-lambdas.
The State monad represents stateful computations i.e. computations that use values from, and perhaps modify, some external state. When you sequence stateful computations together, the later computations might give different results depending on how the previous computations modified the state.
Since functions in Haskell must be pure (i.e. have no side effects) we simulate the effect of external state by demanding that every function takes an additional parameter representing the current state of the world, and returns an additional value, representing the modified state. In effect, the external state is threaded through a sequence of computations, as in this abomination of a diagram that I just drew in MSPaint:
Notice how each box (representing a computation) has one input and two outputs.
If you look at the Monad instance for State you see that the definition of (>>=) tells you how to do this threading. It says that to bind a stateful computation c0 to a function f that takes results of a stateful computation and returns another stateful computation, we do the following:
Run c0 using the initial state s0 to get a result and a new state: (val, s1)
Feed val to the function f to get a new stateful computation, c1
Run the new computation c1 with the modified state s1
How does this work with functions that already take n arguments? Because every function in Haskell is curried by default, we simply tack an extra argument (for the state) onto the end, and instead of the normal return value, the function now returns a pair whose second element is the newly modified state. So instead of
f :: a -> b
we now have
f :: a -> s -> (b, s)
You might choose to think of as
f :: a -> ( s -> (b, s) )
which is the same thing in Haskell (since function composition is right associative) which reads "f is a function which takes an argument of type a and returns a stateful computation". And that's really all there is to the State monad.
Short answer:
State is meant to exploit monads' features in order to simulate an imperative-like system state with local variables. The basic idea is to hide within the monad the activity of taking in the current state and returning the new state together with an intermediate result at each step (and here we have s -> (a,s).
Do not mistake arbitrary functions with those wrapped within the State. The former may have whatever type you want (provided that they eventually produce some State a if you want to use them in the state monad). The latter holds functions of type s -> (a,s): this is the state-passing layer managed by the monad.
As I said, the function wrapped within State is actually produced by means of (>>=) and return as they're defined for the Monad (State s) instance. Its role is to pass down the state through the calls of your code.
Point 3 also is the reason why the state parameter disappears from the functions actually used in the state monad.
Long answer:
The State Monad has been studied in different papers, and exists also in the Haskell framework (I don't remember the good references right now, I'll add them asap).
This is the idea that it follows: consider a type data MyState = ... whose values holds the current state of the system.
If you want to pass it down through a bunch of functions, you should write every function in such a way that it takes at least the current state as a parameter and returns you a pair with its result (depending on the state and the other input parameters) and the new (possibly modified) state. Well, this is exactly what the type of the state monad tells you: s -> (a, s). In our example, s is MyState and is meant to pass down the state of the system.
The function wrapped in the State does not take parameters except from the current state, which is needed to produce as a result the new state and an intermediate result. The functions with more parameters that you saw in the examples are not a problem, because when you use them in the do-notation within the monad, you'll apply them to all the "extra" needed parameters, meaning that each of them will result in a partially applied function whose unique remaining parameter is the state; the monad instance for State will do the rest.
If you look at the type of the functions (actually, within monads they are usually called actions) that may be used in the monad, you'll see that they result type is boxed within the monad: this is the point that tells you that once you give them all the parameters, they will actually do not return you the result, but (in this case) a function s -> (a,s) that will fit within the monad's composition laws.
The computation will be executed by passing to the whole block/composition the first/initial state of the system.
Finally, functions that do not take parameters will have a type like State a where a is their return type: if you have a look at the value constructor for State, you'll see again that this is actually a function s -> (a,s).
I'm total newbie to Haskell and I couldn't understand well the State Monad code in that book, too. But let me add my answer here to help someone in the future.
Answers:
What are they trying to accomplish with State Monad ?
Composing functions which handle stateful computation.
e.g. push 3 >>= \_ -> push 5 >>= \_ -> pop
Why pop takes no parameters, while it is suggested function f takes 1 parameter ?
pop takes no arguments because it is wrapped by State.
unwapped function which type is s -> (a, s) takes one argument. the
same goes for push.
you can unwrapp with runState.
runState pop :: Stack -> (Int, Stack)
runState (push 3) :: Stack -> ((), Stack)
if you mean the right-hand side of the >>= by the "function f", the f will be like \a -> pop or \a -> push 3, not just pop.
Long Explanation:
These 3 things helped me to understand State Monad and the Stack example a little more.
Consider the types of the arguments for bind operator(>>=)
The definition of the bind operator in Monad typeclass is this
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
In the Stack example, m is State Stack.
If we mentaly replace m with State Stack, the definition can be like this.
(>>=) :: State Stack a -> (a -> State Stack b) -> State Stack b
Therefore, the type of left side argument for the bind operator will be State Stack a.
And that of right side will be a -> State Stack b.
Translate do notation to bind operator
Here is the example code using do notation in the book.
stackManip :: State Stack Int
stackManip = do
push 3
pop
pop
it can be translated to the following code with bind operator.
stackManip :: State Stack Int
stackManip = push 3 >>= \_ -> pop >>= \_ -> pop
Now we can see what will be the right-hand side for the bind operator.
Their types are a -> State Stack b.
(\_ -> pop) :: a -> State Stack Int
(\_ -> push 3) :: a -> State Stack ()
Recognize the difference between (State s) and (State h) in the instance declaration
Here is the instance declaration for State in the book.
instance Monad (State s) where
return x = State $ \s -> (x,s)
(State h) >>= f = State $ \s -> let (a, newState) = h s
(State g) = f a
in g newState
Considering the types with the Stack example, the type of (State s) will be
(State s) :: State Stack
s :: Stack
And the type of (State h) will be
(State h) :: State Stack a
h :: Stack -> (a, Stack)
(State h) is the left-hand side argument of the bind operator and its type is State Stack a as described above.
Then why h becomes Stack -> (a, Stack) ?
It is the result of pattern matching against the State value constructor which is defined in the newtype wrapper. The same goes for the (State g).
newtype State s a = State { runState :: s -> (a,s) }
In general, type of h is s ->(a, s), representation of the stateful computation. Any of followings could be the h in the Stack example.
runState pop :: Stack -> (Int, Stack)
runState (push 3) :: Stack -> ((), Stack)
runState stackManip :: Stack -> (Int, Stack)
that's it.
The State monad is essentially
type State s a = s -> (a,s)
a function from one state (s) to a pair of the desired result (a) and a new state. The implementation makes the threading of the state implicit and handles the state-passing and updating for you, so there's no risk of accidentally passing the wrong state to the next function.
Thus a function that takes k > 0 arguments, one of which is a state and returns a pair of something and a new state, in the State s monad becomes a function taking k-1 arguments and returning a monadic action (which basically is a function taking one argument, the state, here).
In the non-State setting, pop takes one argument, the stack, which is the state. So in the monadic setting, pop becomes a State Stack Int action taking no explicit argument.
Using the State monad instead of explicit state-passing makes for cleaner code with fewer opportunities for error, that's what the State monad accomplishes. Everything could be done without it, it would just be more cumbersome and error-prone.

Resources