3 ms·
While getting at a real issue, people are being sloppy with what they mean by "monads" and "compose" on both sides of it. Types which are monads compose to mak
by dllthomas 5y ago
While getting at a real issue, people are being sloppy with what they mean by "monads" and "compose" on both sides of it.
Types which are monads compose to make types that are definitely functors but maybe (probably?) not monads. That "maybe not" is what type theory people mean when they say "monads don't compose" but it's mostly not what's bugging people because...
Most monads can be rewritten as monad transformers (where applying them to the identity monad reproduces the original monad), which do compose in that way, and this is often what people do in Haskell when they have code that needs multiple effects.
But! Values of different types (like, say, a `WriterT t (Identity u)` and a `WriterT t (IO u)` can't be composed using the ever-so-convenient Monad interface which is the reason we wanted to make things Monads in the first place. This is what the article is discussing and it's what programmers often mean when they say "monads don't compose".
The workaround in the Haskell ecosystem (at least in those parts that haven't adopted effect systems or free monads w/ interpreters) is to write as much of your logic as possible using an unspecified monad, only asking for the functionality you need by way of constraints. Constraints compose like gangbusters! Values with unifiable types that have different sets of constraints? Well, it must've been a type that satisfies all of those constraints. And the abstract type is a nice place to stick in mocks as you test the pieces of things.
This shares much of the downside of effect sets, in that it is awkward to specify order ("layering"?) of effects when they do matter; it's possible to be more concrete about the types for those pieces but it does spread to the pieces that contain them and can sometimes get boilerplatey. Whether that's worth it for the added safety is going to be context dependent.