class Monad m => MonadState s m | m -> s where
-- | Return the state from the internals of the monad.
get :: m s
get = state (\s -> (s, s))
-- | Replace the state inside the monad.
put :: s -> m ()
put s = state (\_ -> ((), s))
-- | Embed a simple state action into the monad.
state :: (s -> (a, s)) -> m a
state f = do
s <- get
let ~(a, s') = f s
put s'
return a
instance MonadState s m => MonadState s (MaybeT m) where...
Why does a instance of MonadState need a state and a monad, why not create a single parameter State class?
Let me try and answer Gert's question in the comments, because it's a pretty different question.
The question is, why can we not just write
class State s where
get :: s
put :: s -> ()
Well, we could write this. But now the question is, what can we do with it? And the hard part is, if we have some code with put x and then later get, how do we link the get to the put so that the same value is returned as the one put in?
And the problem is, with just the types () and s, there is no way to link one to the other. You can try implementing it in various ways, but it won't work. There's just no way to carry the data from the put to the get (maybe someone can explain this better, but the best way to understand is to try writing it).
A Monad is not necessarily the only way to make operations linkable, but it is a way, because it has the >> operator to link two statements together:
(>>) :: m a -> m b -> m b
so we can write
(put x) >> get
EDIT: Here is an example using the StateT instance defined in the package
foo :: StateT Int IO ()
foo = do
put 3
x <- get
lift $ print x
main = evalStateT foo 0
You need some way of associating the type of the state to the type of the monad. MultiParamTypeClasses with FunctionalDependencies is one way. However, you can also do it using TypeFamilies.
class (Monad m) => MonadState m where
type StateType m
-- | Return the state from the internals of the monad.
get :: m (StateType m)
get = state (\s -> (s, s))
-- | Replace the state inside the monad.
put :: StateType m -> m ()
put s = state (\_ -> ((), s))
-- | Embed a simple state action into the monad.
state :: (StateType m -> (a, StateType m)) -> m a
state f = do
s <- get
let ~(a, s') = f s
put s'
return a
instance MonadState m => MonadState (MaybeT m) where
type StateType (MaybeT m) = StateType m
...
This is the approach taken by the monads-tf package.
Related
I have trouble even explaining what I'm trying to do, please bear with me. I haven't really grasped type theory, or how to use forall so that is probably the reason why wording (and implementing) this is difficult for me. So basically I'm trying to replicate the behaviour of MonadIO with a MonadTransformer. MonadIO is defined as
class (Monad m) => MonadIO m where
-- | Lift a computation from the 'IO' monad.
liftIO :: IO a -> m a
-- | #since 4.9.0.0
instance MonadIO IO where
liftIO = id
This code compiles (I haven't included the Applicative and Functor instances here though, but I can):
newtype Debugable m r = Debugable { runDebugable :: (DebugState -> m (DebugState, r)) }
instance MonadTrans (Debugable) where
lift action = Debugable $ \d -> do
r <- action
return (d, r)
class (Monad i, Monad m) => MonadDebug i m where
liftDebug :: Debugable i a -> m a
instance (Monad m) => MonadDebug m (Debugable m) where
liftDebug = id
I want to write a method like this, that should work in any MonadTransformer above MonadDebug in the transformer stack:
debug :: (MonadDebug i m) => String -> m ()
debug msg = liftDebug $ doDebug msg
(doDebug operates in the Debugable monad)
Of course this does not compile because the type variable i cannot be deduced (or something like that)... I tried a few things, but I don't really understand what the debug messages mean either. I don't even know if a generalized lifting of a MonadTransformer similar to liftIO is possible... Is it?
I suggest changing your goal slightly.
The idiomatic way to make this class is to expose all of the base transformer's operations as class methods, rather than exposing a lifting transformation. Like this:
class Monad m => MonadDebugable m where
debug :: (DebugState -> (DebugState, r)) -> m r
instance Monad m => MonadDebugable (Debugable m) where
debug f = Debugable (pure . f)
instance MonadDebugable m => MonadDebugable (ReaderT r m) where
debug = lift . debug
-- and a dozen other instances for other transformers
Then you can offer derived operations, like, say,
observeCurrentState :: MonadDebugable m => m DebugState
observeCurrentState = debug (\s -> (s, s))
recordState :: MonadDebugable m => DebugState -> m ()
recordState s = debug (\_ -> (s, ()))
debugMsg :: MonadDebugable m => String -> m ()
debugMsg msg = debug (\s -> (s { messages = msg : messages s }, ())) -- or whatever
Then, in all your client code, where you would originally have written liftDebug foo, you simply write foo (but using operations like those above that are polymorphic over which exact monad stack you're using at the moment).
Of course, the obvious follow-up question is: what's the deal with MonadIO, then? Why doesn't IO follow this pattern? The answer there is that IO just has too many primitive operations to write a sensible class -- indeed, with the FFI, it's even possible for libraries and users to add new primitives. So we have to go with the slightly less desirable solution there, where we must annotate all our primitive calls with liftIO if we're not exactly in IO already. Skipping the annotations, like above, would be nicer, but we just can't have it.
I have function:
step :: forall m . (MonadState IntCodeState m) => m (Maybe ())
When I use do notation in the body of the function, it uses m as the monad. As you might expect, I actually want it to be using m Maybe. But, it doesn't understand that m Maybe is a monad. How do I express that to Haskell?
EDIT: This may be slightly malformed at the moment. The concrete type should be
StateT IntCodeState Maybe (), but I'm trying not to declare the concrete type, so the question is: how do I declare that?
EDIT 2: Another attempt: I've got some functions that look like this:
getValueIndex :: (MonadState IntCodeState m) => Int -> m (Maybe Int)
Here, I'm working on the level of the state monad. However, I now want to be able to act "as if" m Maybe was the monad. I was hoping this was simple but I can't figure out a way of expressing it. The code I want to write looks like this
step :: forall m . (MonadState IntCodeState m) => m (Maybe ())
step = do
full <- opCode
let len = length (snd full) + 1
process full <* (next += len)
But opCode returns a m (Maybe a) and I want full to be an a
But opCode returns a m (Maybe a) and I want full to be an a
Looks like you want to use the MaybeT monad transformer, which is m (Maybe a) under the hood, with its Monad instance doing what you need:
The MaybeT monad transformer extends a monad with the ability to exit the computation without returning a value.
A sequence of actions produces a value only if all the actions in the sequence do. If one exits, the rest of the sequence is skipped and the composite action exits.
Here are the types:
MaybeT :: m (Maybe a) -> MaybeT m a
runMaybeT :: MaybeT m a -> m (Maybe a)
This will also be helpful, specialised from MonadTrans:
lift :: m a -> MaybeT m a
So in your case:
step :: forall m . (MonadState IntCodeState m) => m (Maybe ())
step = runMaybeT $ do
full <- MaybeT opCode -- :: MaybeT opCode :: MaybeT m a, full :: a
let len = length (snd full) + 1
lift $ process full <* (next += len)
I've assumed process returns an m () and used lift to change it into MaybeT m ().
I have recently decided to start using monad transformations instead of stacking my monads, since it seems it's the right thing to do. I wasn't really stacking many monads before anyway. I get (I think) the idea behind it and the lift function, that, as I understand it, acts as a sort of return for the transformation (puts something from the underlying monad into the transformed monad).
So far so good, but I don't see anything similar to an fmap function for monad transformations. Let me give you an example. Say I have a custom monad, m, and I use a StateT transformation on it, therefore using the type StateT s m a instead of m (State s a).
Now, it so happens that in my monad m, I have a function that transforms the monadic element (in fact it is one of the constructors of the monad, if you need details I can give) while keeping in some sense the underlying values: myFunc :: m a -> m a.
So I'm building a recursive function recFunc :: State s a -> [t] -> m (State s a) that looks similar to something like this:
recFunc :: State s a -> [t] -> m (State s a)
recFunc x [] = return x
recFunc x (t:ts) = myFunc (recFunc x ts)
But if I try to replicate this using monad transformations, I run into problems because I can find no way to plug in myFunc into the mix. It does not matter whether you write the input as State s a or as StateT s Identity a (which would be algebraically more precise?)
recFuncT :: StateT s Identity a -> [t] -> StateT s m a
recFuncT x [] = ???
recFuncT x (t:ts) = ????? where rec = recFuncT x ts
So what I'm looking for is something like the (invented, and don't know how I would implement, if possible) following functions:
transmap :: (MonadTrans t, Monad m) => (forall b. m b -> m b) -> t m a -> t m a
transmap = ???
transreturn :: (MonadTrans t, Monad m) => m (t Identity a) -> t m a
transreturn = ???
I have the feeling I should be able to define these using lift, but I don't see how, to be honest.
If I had them, then I could do this:
recFuncT :: StateT s Identity a -> [t] -> StateT s m a
recFuncT x [] = transreturn (return x)
recFuncT x (t:ts) = transmap myFunc (recFuncT x ts)
Maybe what I really want is something more basic. I want the assumed isomorphism between t m a and m (t Identity a) to be explicit, so I'm looking for functions:
fromTrans :: t m a -> m (t Identity a)
toTrans :: m (t Identity a) -> t m a
As far as I understand monad transformers, these functions should always exist and be fairly straightforward, right?
With these I could obviously implement transmap and transreturn:
transmap :: (MonadTrans t, Monad m) => (forall b. m b -> m b) -> t m a -> t m a
transmap f x = toTrans (f (fromTrans x))
transreturn :: (MonadTrans t, Monad m) => m (t Identity a) -> t m a
transreturn = toTrans
I am sure there is something obvious that I am overlooking. Please point at it for me.
Thanks.
It appears that one concept you're seeking can be found in the mmorph package:
class MFunctor t where
-- The argument is generally required to be a monad morphism,
-- but some instances will work sensibly when it's not.
hoist :: Monad m => (forall x. m x -> n x) -> t m a -> t n a
This is a little more general than your version because it allows the underlying monad to be replaced.
From the discussion in the comments, it sounds like what you really want is a monad transformer for your custom monad that is then applied to the base monad State. In other words, to the extent that your custom monad is "nearly" a list:
newtype Listish a = Listish [a]
its transformer version would have type:
newtype ListishT m a = ListishT [m a]
and so your final monad transformer stack would be:
type M s = ListishT (State s)
which is isomorphic to your monad stack
[State s a] AKA Listish (State s a)
Be sure not to over-generalize the pattern for creating a transformer from an underlying monad, however. While transformers for some monads:
newtype List a = List [a]
newtype Reader r a = Reader (r -> a)
are sensibly derived by replacing "a" with "m a":
newtype ListT m a = ListT [m a]
newtype ReaderT r m a = ReaderT (r -> m a)
transformers for other types are derived differently. For example:
newtype State s a = State (s -> (a, s))
newtype Writer w a = Writer (a, w)
give:
newtype StateT s a = StateT (s -> m (a, s))
-- **NOT** StateT (s -> (m a, s))
newtype WriterT s a = WriterT (m (a, w))
-- **NOT** WriterT (m a, w)
In particular, there is no monad transformer for IO, because the simple substitution
newtype BadIOT m a = BadIOT (IO (m a))
is, as you point out, silly.
EDIT: All of the below makes no sense. I leave it strikedthrough. Good answer below.
For the record, my final solution was neither to use or implement a monad transformer, and instead simply implement the following function: (my custom monad is called EnumProc):
(..>>=) :: Monad m => EnumProc (m a) -> (a -> m b) -> EnumProc (m b)
en ..>>= f = en <$> (>>= f)
infixl 7 ..>>=
This allows me to deal with monadic computations inside my monad while keeping the outside monad structure. I was surprised myself when an fmap sufficed.
I then use EnumProc (State s a) as type throughout.
After a while, I finally came up with exactly what I was looking for since the beginning. I can use StateT exactly the way I wanted, and it has exactly the semantics I thought it had, but I did not explain it well (and put mistakes in what I wrote).
Going back to my original post, I need not have a State as input, the State/StateT monad already includes the input in the monadic element. So what I needed was a function recFuncT :: [t] -> StateT s m a that behaved equivalently to the following non-transformer one:
recFunc :: a -> [t] -> m (State s a)
recFunc x [] = return (return x)
recFunc x (t:ts) = myFunc (recFunc x ts)
It can be implemented directly, using the constructor StateT and runStateT. Here it is:
recFuncT :: a -> [t] -> StateT m s a
recFuncT x [] = return x
recFuncT x (t:ts) = StateT (\s -> myFunc (runStateT (recFuncT x ts) s))
Moreover, the function transmap can also be implemented in general, at least for StateT:
transmap :: Monad m => (forall b. m b -> m b) -> StateT s m a -> StateT s m a
transmap f st = StateT (\s -> f (runStateT st s)
And then we could write recFuncT nicely in terms of it:
recFuncT :: a -> [t] -> StateT m s a
recFuncT x [] = return x
recFuncT x (t:ts) = transmap myFunc (recFuncT x ts)
I realize this does not really match with the code that I included originally, but it does match with the overall principle I was trying to appeal to saying that the StateT transformer is like adding state to my monad m, and therefore anything that can be done at the m (State s a) level can be done at the StateT s m a level.
How to use MonadBaseControl from monad-control to lift simpleHTTP function defined in happstack-server?
Current type of simpleHTTP:
simpleHTTP :: ToMessage a
=> Conf -> ServerPartT IO a -> IO ()
Expected type of simpleHTTPLifted:
simpleHTTPLifted :: (MonadBaseControl IO m, ToMessage a)
=> Conf -> ServerPartT m a -> m ()
My current attempt (does not compile):
simpleHTTPLifted conf action =
liftBaseWith (\runInBase ->
let
fixTypes :: UnWebT m a -> UnWebT IO a
fixTypes c = runInBase c
in simpleHTTP conf (mapServerPartT fixTypes action)
)
Note that similar puzzle is in my related question: MonadBaseControl: how to lift ThreadGroup
I'd like to understand how to in general lift such functions and what are usual steps taken when presented with such a type puzzle?
EDIT: I guess I need a function of type (StM m a -> a). restoreM is pretty close, but does not make it. I've also found an ugly version of fixTypes:
fixTypes :: UnWebT m a -> UnWebT IO a
fixTypes c = do
x <- newIORef undefined
_ <- runInBase (c >>= liftBase . writeIORef x)
readIORef x
This relies on IO being the base monad which is not an optimal solution.
I don't think you can lift this in general for any MonadBaseControl IO m. There are some ms for which we can.
In General
UnWebT m is isomorphic to WebT m which has a MonadTransControl instance. You can convert to and from WebT with mkWebT :: UnWebT m a -> WebT m a and ununWebT :: WebT m a -> UnWebT m a.
MonadBaseControl is a fancy wrapper around a stack of MonadTransControl transformers that flattens the stack so that running and restoring state happens all the way down the stack and all the way back up it again. You can understand MonadBaseControl by understanding MonadTransControl, which I'll repeat briefly here:
class MonadTrans t => MonadTransControl t where
data StT t :: * -> *
liftWith :: Monad m => (Run t -> m a) -> t m a
restoreT :: Monad m => m (StT t a) -> t m a
type Run t = forall n b. Monad n => t n b -> n (StT t b)
The class says with liftWith, "I'll provide a temporary way to run t ms in m, which you can use to build actions in m, which I will in turn run." The StT type of the result says, "the results of the t m things I run in m for you aren't going to be generally available in t m; I need to save my state somewhere, and you have to give me a chance to restore my state if you want the results."
Another way of saying approximately the same thing is, "I can temporarily unwrap the base monad". The question of implementing fixTypes is reduced to "Given that we can temporarily unwrap a WebT from an m and can temporarily unwrap an m from IO, can we permanently unwrap an m from an IO?" for which the answer, barring the capabilities of IO, is almost certainly "no".
IO Tricks
I suspect that there exist ms such that the "ugly" fixTypes will do horrible things like never call writeIORef and thus return undefined or execute code asynchronously and therefore call writeIORef after readIORef. I'm not sure. This is made complicated to reason about due to the possibility that the action created by liftBaseWith is never used in such degenerate cases.
For Comonads
There should be a way to lift simpleHttp without IO tricks precisely when the state of the monad m is a Comonad and therefore has a function extract :: StM m a -> a. For example, this would be the case for StateT s m which essentially has StM s a ~ (s, a).
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Happstack.Server.SimpleHTTP
import Control.Comonad
import Control.Monad.Base
import Control.Monad.Trans.Control
simpleHTTPLifted :: forall m a. (MonadBaseControl IO m, Comonad (StM m), ToMessage a)
=> Conf -> ServerPartT m a -> m ()
simpleHTTPLifted conf action =
liftBaseWith (\runInBase ->
let
fixTypes :: UnWebT m b -> UnWebT IO b
fixTypes = fmap extract . runInBase
in simpleHTTP conf (mapServerPartT fixTypes action)
)
In practice this isn't very useful because the newtypes defined in the older versions of monad-control don't have Comonad instances and the type synonymns in the newer versions of monad-control make no effort to have the result as the last type argument. For example, in the newest version of monad-control type StT (StateT s) a = (a, s) .
Have you already seen the following function? What is it called? What is it useful for? can it be defined more generically than just for StateT?
simpleFunction (StateT f) = StateT $ (\s -> return (f s, s))
By the way, ghc gives it the type Monad n => StateT s m a -> StateT s n (m (a, s)).
And there is an alternative definition:
simpleFunction m = do
s <- get
mapStateT (\l -> return (l, s)) m
Having two monads like n (m a) isn't usually very useful (the composition might not be a monad etc.). So I guess more usable version would be of type
(Monad m) => StateT s m a -> StateT s m (a, s).
This can be generalized to an arbitrary state transformer over m:
import Control.Monad
import Control.Monad.State
f1 :: (MonadState s (t m), MonadTrans t, Monad m) => StateT s m a -> t m (a, s)
f1 (StateT f) = get >>= lift . f
And since the only thing we need is get, we can further generalize to:
f2 :: (MonadTrans t, Monad m, Monad (t m)) => t m s -> StateT s m a -> t m (a, s)
f2 g (StateT f) = g >>= lift . f
If you really need to have two monads, perhaps MFunctor would be useful - functions like hoist or generalize allow to switch between monads.
The simpleFunction structure is parameterized over two things: a StateT monad and a function f. As it is shown in both given definitions, the simpleFunction gets the state from the internals of the monad, then map both the return value and final state of a computation using a given function.
Following a very simple example to see a working example:
import Control.Monad.State
inc :: State Int Int
inc = do
n <- get
put (n + 1)
return n
simpleFunction = do
s <- get
mapState (\l -> (l,s)) inc
main = do
print $ runState simpleFunction 1
The result is: ((1,2),1) which is the ((return value,final state),initial state)
The simpleFunction as you see is not complicated. It can be used with monads other than StateT. In this case, you have to implement your own map and get.
Hope it's useful!