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

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.

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.

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

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).

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

Haskell State Monad

Does the put function of the State Monad update the actual state or does it just return a new state with the new value? My question is, can the State Monad be used like a "global variable" in an imperative setting? And does put modify the "global variable"?
My understanding was NO it does NOT modify the initial state, but using the monadic interface we can just pass around the new states b/w computations, leaving the initial state "intact". Is this correct? if not, please correct me.
The answer is in the types.
newtype State s a = State {runState :: s -> (a, s)}
Thus, a state is essentially a function that takes one parameter, 's' (which we call the state), and returns a tuple (value, state). The monad is implemented like below
instance Monad (State s) where
return a = State $ \s -> (a,s)
(State f) >>= h = State $ \s -> let (a,s') = f s
in (runState h a) s'
Thus, you have a function that operates on the initial state and spits out a value-state tuple to be processed by the next function in the composition.
Now, put is the following function.
put newState = State $ \s -> ((),newState)
This essentially sets the state that will be passed to the next function in the composition and the downstream function will see the modified state.
In fact, the State monad is completely pure (that is, nothing is being set); only what is passed downstream changes. In other words, the State monad saves you the trouble of carrying around a state explicitly in a pure language like Haskell. In other words, State monad just provides an interface that hides the details of state threading (that's what is called in the WikiBooks and or Learn you a Haskell, I think).
The following shows this in action. You have get, which sets the value field to be the same as the state field (Note that, when I mean setting, I mean the output, not a variable). put gets the state via the value passed to it, increments it and sets the state with this new value.
-- execState :: State s a -> s -> s
let x = get >>= \x -> put (x+10)
execState x 10
The above outputs 20.
Now, let's do the following.
execState (x >> x) 10
This will give an output of 30. The first x sets the state to 20 via the put. This is now used by the second x. The get at this point sets the state passed it to the value field, which is now 20. Now, our put will get this value, increment it by 10 and set this as the new state.
Thus, you have states in a pure context. Hope this helps.
There's nothing magical about State. You could implement it like this:
newtype State s a = State {runState :: s -> (a, s)}
That is, a State s a (which we think of as a computation that uses a state of type s to produce a result of type a) is just a function that takes a state and returns a result and a new state. You should attempt to write out the Monad instance and definitions of get and put for this definition. The real definition is more general:
type State s = StateT s Identity
newtype Identity a = Identity a
newtype StateT s m a = StateT {runStateT :: s -> m (a, s)}
This allows state to be added to other monadic computations. It's also possible to define state transformers as "operational monads". Apfelmus has a tutorial on those somewhere.
First, the state isn't "global" as such; you could have several different copies of the state monad running, each with its own independent state, and they won't interfere with each other. (Indeed, that's arguably the whole point.) If you wanted the state to be global to the entire program, you'd have to put the entire program into a single state monad.
Second, calling put changes the result that subsequent calls to get will return. That's all. It doesn't "change" the actual value itself. Like, if you call get and put the result into a variable somewhere, and then call put, your variable won't change. Even if the state is a dictionary or something, if you were to add a new key and put that, anybody still looking at the old copy of the dictionary will still see the old dictionary. This isn't special to the state monad; it's just how Haskell works.

Haskell -- dual personality IO / ST monad?

I have some code that currently uses a ST monad for evaluation. I like not putting IO everywhere because the runST method produces a pure result, and indicates that such result is safe to call (versus unsafePerformIO). However, as some of my code has gotten longer, I do want to put debugging print statements in.
Is there any class that provides a dual-personality monad [or typeclass machinery], one which can be a ST or an IO (depending on its type or a "isDebug" flag)? I recall SPJ introduced a "Mutation" class in his "Fun with Type Functions" paper, which used associative types to relate IO to IORef and ST to STRef. Does such exist as a package somewhere?
Edit / solution
Thanks very much [the nth time], C.A. McCann! Using that solution, I was able to introduce an additional class for monads which support a pdebug function. The ST monad will ignore these calls, whereas IO will run putStrLn.
class DebugMonad m where
pdebug :: String -> m ()
instance DebugMonad (ST s) where
pdebug _ = return ()
instance DebugMonad IO where
pdebug = putStrLn
test initV = do
v <- newRef initV
modifyRef v (+1)
pdebug "debug"
readRef v
testR v = runST $ test v
This has a very fortunate consequence in ghci. Since it expects expressions to be IO types by default, running something like "test 3" will result in the IO monad being run, so you can debug it easily, and then call it with something like "testR" when you actually want to run it.
If you want a unified interface to IORef and STRef, have you looked at the stateref package? It has type classes for "references to mutable data", separated for readable, writable, etc., with instances for IORef and STRef, as well as things like TVar, MVar, ForeignPtr, etc.
Have you considered Debug.Trace.trace instead?
http://www.haskell.org/haskellwiki/Debugging

Resources