3 ms·
I think monads are what we would ordinarily call "environment" or "context" of execution. Monad just describes how to compose the interactions with the context.
by js8 5y ago
I think monads are what we would ordinarily call "environment" or "context" of execution. Monad just describes how to compose the interactions with the context. Usually this is some serialization of these interactions but can be other things.
IO monad is where the environment (context of execution) is just your entire operating system. In imperative languages, this is a normal state of affairs, but functional programmers view that with similar suspicion that most programmers of today view global variables.
That's why in general "different monads don't compose", because it's like trying to compose two different environments (as we know, for example, porting between different OSes is not trivial). You can define it (with monad transformers) but it's often a lot of work.
- hither_shores 5y agoMore precisely: the composition of two different monads isn't always a monad. `[IO Int]` is a perfectly sensible type, you just can't flatten a `[IO [IO Int]]`.
- tromp 5y agoIsn't that what joinMMT [1] is for ? [1] https://hackage.haskell.org/package/TypeCompose-0.9.14/docs/Control-Compose.html#v:joinMMT https://hackage.haskell.org/package/TypeCompose-0.9.14/docs/...
- tome 5y agoThat particular function won't work because IO is not Traversable.
- js8 5y agoI think (I am not sure) that you cannot define monad composition (transformer) with IO because IO is purposely open-world (so that Haskell can use C libraries and OS calls) and as such is not entirely formally defined. If we defined it as a closed-world, i.e. these are the side effects that you can do with IO and nothing else, then it might become possible to compose with other monads.
- hither_shores 5y agoMonad transformers aren't quite the same thing as composed monads. (In fact, they're kind of a kludge to deal with the fact that monad composition isn't very well behaved.) Some monad transformers, like `MaybeT m a`, are just wrappers around a composed `m (Maybe a)`, but others, like the continuation passing transformer `ContT r m a = (a -> m r) -> m r`, are very much not.