## Function in Haskell to map over a MonadTrans?

haskell state monad

haskell lift

monad transformers haskell

haskell monadplus

liftio haskell

haskell writert

haskell readert

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.

**Control.Monad.Trans.Class,** All of the monad transformers except ContT and SelectT are functors on the they also define a mapping from transformations between base monads to " Monadic parsing in Haskell", by Graham Hutton and Erik Meijer, Journal of Functional� (Currently these functions are defined as field labels, but in the next major release they will be separate functions.) All of the monad transformers except ContT and SelectT are functors on the category of monads: in addition to defining a mapping of monads, they also define a mapping from transformations between base monads to transformations

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.

**All About Monads,** 3.4.1 The MonadTrans and MonadIO classes; 3.4.2 Transformer The mapM function maps a monadic computation over a list of values and� Map both the return value and the state of a computation using the given function. mGetRaw :: Monad m => MultiWriterT a m ( HList a) Source # A raw extractor of the contained HList (i.e. the complete state).

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.

**Chapter 18. Monad transformers,** Before we introduce monad transformers, let's look at a function written using techniques we are already familiar with. Monad.Trans (liftIO) import Control. Monad. We use a WriterT on top of IO because there is no IOT monad transformer. For teaching the language, it's good that map operates on lists, not on functors. The MonadTransControl type class is a stronger version of MonadTrans:. Instances of MonadTrans know how to lift actions in the base monad to the transformed monad. These lifted actions, however, are completely unaware of the monadic state added by the transformer.

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.

**Stacking the ReaderT WriterT Monad Transformer Stack in Haskell,** Stacking the ReaderT WriterT Monad Transformer Stack in Haskell. January 12 local - to map a function on the resource before using it: local :: (r -> r) Let's also have a look at the MonadTrans typeclass. It defines one� The mapAndUnzipM function maps its first argument over a list, returning the result as a pair of lists. This function is mainly used with complicated data structures or a state-transforming monad. This function is mainly used with complicated data structures or a state-transforming monad.

**Issue deriving MonadTrans for chained custom monad transformers ,** After defining a set of monadic functions for this monad, I wanted to build a second Can't make a derived instance of 'MonadTrans CommandT' (even with cunning Window XRect)) deriving (Input (M.Map Window XRect), Output (M. Map little surprised to find no discussion on this given the overlap between the Haskell� Then we can perform three different lifting operations: liftM can be used both to transform a pure function into a function between inner monads and to a function between transformed monads, and finally lift transforms from the inner monad to the transformed monad. Because of the purity of Haskell, we can only lift "up".

**Haskell Basics,** Functions are the primary building block of all of Haskell logic. the Functor typeclass allows us to "map" a function generically over any type of Monad. Trans. Since many function names (but not the type name) clash with Prelude names, this module is usually imported qualified, e.g. import Data.Map (Map) import qualified Data.Map as Map The implementation of Map is based on size balanced binary trees (or trees of bounded balance) as described by:

**CMSC-16100 — Lecture 23: Monad Transformer Library ,** class MonadTrans t where lift :: Monad m => m a -> t m a. i.e., IdentityT possesses a lift function that maps the untransformed monad m a into the Lazy relies on functional dependencies, an extension to Haskell implemented in GHC, but not� Note the kind signature of instances of the MonadTrans class: (*-> *)-> (*-> *). That is, every monad transformer type constructor takes a monad (kind *-> *) as an argument, and returns a monad (also *-> *) as a result. So all Monad Transformers are basically type-functions from monad types to different monad types which have additional traits.

##### Comments

`State s a == StateT s Identity a`

, so`StateT s m a`

and`m (StateT s Identity a)`

are two different things. One is isomorphic to`m (s -> (a, s))`

, the other`s -> m (a, s)`

.- @chepner That is a fair point, but even if that is true, it still does not address my high level issue, namely: I am assuming the principle that if a monad has an associated transformer, then anything you can do by stacking monads you can do by using the transformer, call it the "Transformer Principle". So what I am trying to do, you can do by stacking monads, as showcased by my implementation
`recFunc`

. Therefore, if the principle holds (and since the`State`

monad does have a transformer), there must be a way to do it with transformers. What is that way? - Yes, but your conversion isn't just stacking monads.
`recFuncT`

is*different*than`recFunc`

. If it were the same, you wouldn't have to change the body at all, because simply replacing`State`

with the equivalent`StateT`

is just alias expansion. - @chepner I am pretty sure you must be missing the point. you can always replace
`State`

with`StateT`

, but not all instances of`StateT`

can be directly replaced with an instance of`State`

. That is, whenever`m`

is not the Identity, then`StateT s m a`

cannot be rewritten in terms of`State`

. However, conceptually and as I understand transformers,`StateT s m a`

is "inserting`State`

capabilities inside`m`

", and so should have at least all the functionality of`m (State s a)`

. Are you saying this is not true, that there are things you can only do with`m (State s a)`

? - I think the problem is that
`StateT s m a`

can be viewed as "inserting`State`

capabilities inside`m`

", but the type`m (State s a)`

can't. It's not even clear what`m (State s a)`

*is*, at least for general monad`m`

. What's`IO (State s a)`

? If it's supposed to be a monad, what does its bind operator look like? If it's not supposed to be a monad, what are its "capabilities"? - It even has a predefined instance
`MFunctor (StateT s)`

, which is exactly what I wanted. This is exactly the answer I was initially looking for. - Hm. But you could define that for any monad and it would not make sense. Why would it make more sense for this monad? You could implement:
`newtype TransformerFromMonad tm m a = TransformerFromMonad (tm (m a))`

And then consider horrifying things like`TransformerFromMonad IO (State s) == IO (State s a)`

and which is nothing like a transformer for the`IO`

monad. - I added a note about this.
- Maybe I am trying to generalize monad transformers too much, instead of taking them individually for what each of them are...
- Because of my low rep it doesn't let me set this one as accepted in the end. I realize I've changed my mind and changed the phrasing of the problem many times, but as I understand it this is normal when I am not an expert in what I'm talking about. I don't know what are exactly the policies of Stack Overflow when it comes to trying to leave this as not-a-mess. Let me know if I need to edit something, merge something, delete something or anything else and I'll try to do it. Thanks again to those who helped me get to the core of it.