While looking through the transformers package, I found this monad transformer called IdentityT.
Although I understand how the Identity monad is used (e.g. State
is just an alias for StateT Identity
) and how monad transformers work in general, I have no idea how that relates to IdentityT
.
Since it's not in the MTL, I'm guessing it was added in there just for completeness and has no practical use. Is that correct?
Well the linked documentation does say
This is useful for functions parameterized by a monad transformer.
Though I'm not aware of any situations where this is actually the case. Theoretically if you have a function like foo :: (MonadTrans t, Monad m) => t m a -> b
for some useful b
, then you might want to be able to "dumb it down" to essentially m a -> b
by using t = IdentityT
.
But IdentityT
is to MonadTrans
what Identity
is to Monad
. It is the "pass-through" transformer, as Identity
is the "pass-through" monad. Just check out the source; it's rather simple. IdentityT SomeMonad a
should behave identically to SomeMonad a
, the only difference being the presence of an extra newtype (which, of course, is removed at compile time)
There's a proposed usage here (presumably the origin of IdentityT: http://www.haskell.org/pipermail/libraries/2007-June/007563.html
The main use seems to be to allow flexibility at the source code level, e.g. someone can edit the source to xmonad and substitute their own UserT without editing too much code.
I tried to see how that could work for a library - you can use it to provide a placeholder for inserting a monad in the middle of a stack, I'm not sure of a great case for that though. Here's my contrived example:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Main where
import Control.Monad.State
import Control.Monad.List
import Control.Monad.Reader
type X m a = StateT Int (m IO) a
something :: (Monad (m IO), MonadIO (m IO)) => (m IO) Int -> X m Int
something a = do
x <- lift a
put (x + 1)
liftIO $ print x
return x
listSomething = something $ ListT (mapM return [1,2,3,4])
plainSomething = return 5 :: IdentityT IO Int
main = do
x <- runListT (execStateT listSomething 3)
print x
y <- runIdentityT (execStateT plainSomething 3)
print y
runIdentity $ mapM (return . (+1)) [1..100]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With