Hi all,
I was experimenting with monad transformers and realized that the stacking order of the monads can remain unknown until it is used. Take for example the following code:
import "mtl" Control.Monad.State
import "mtl" Control.Monad.Writer
import "mtl" Control.Monad.Identity
test :: (MonadWriter [Char] m, Num t, MonadState t m) => m ()
test = do
put 1
tell "hello"
main = do
x <- return $ runIdentity $ runStateT (runWriterT test) 1 -- test :: WriterT String (StateT Int Identity)
y <- return $ runIdentity $ runWriterT $ runStateT test 1 -- test :: StateT Int (WriterT String Identity)
z <- runWriterT $ runStateT test 1 -- test :: StateT Int (WriterT String IO) (((), Int), String)
print x
print y
print z
*Main> main
(((),"hello"),1)
(((),1),"hello")
(((),1),"hello")
Until test is called in 'main' we don't know the order of monads. In fact even the base monad is not know. All we know is that it uses the State and Writer monad. In each call to 'test' in main we can determine the stacking order and the base monad yielding different results. This seems to be a more flexible way of using monad transformers but I haven't seen this in code before so is there anything wrong with this style?
-deech