Most of the monads I can think of belong in one or both of these categories:
State
Can be modelled as a state monad
Reader
Writer
State
ST
STM
function (((->) r))
Identity (state with no state)
Error
Sequencing with early exit
Maybe
Either
ErrorT
Both
IO (with the real world as state)
parser combinators
The only (useful) exception I can think of, whose functionality is clearly distinct from both these categories, is List (and Cont, which is merely a generalization of Monad itself).
Are there any other monads, that canāt be modelled exclusively by either category, that I have missed?
I see your point. By error, I mean ājust perform regular pure (or stateful) computation, unless stopped by some exceptional condition,ā i.e. only carrying a single (optional) value. List does more than that, in that it applies computation to multiple items, so it canāt be āclassedā with the error monads, under my definition.
My objective is to provide a perspective on monads from a practical (maybe application) programmerās perspective. Iām musing that maybe monads are over-abstracted, and itās possible to define an easier-to-reason-about abstraction based on the concepts of state and early exit for practical programming.
For me personally, I donāt even find the list monad useful - i find it obfuscates more than writing the code explicitly, and doesnāt really give any helpful intuitions. Iād be curious to hear if someone has a different perspective.
Iād argue that monad transformers are really useful but also very clunky without MTL/some effect system, either of which need abstract monads. Being able to mix state+non-determinism or streaming+async+resource management seems a lot harder without abstract monads.
For extra monad types: There is a (maybe a bit underused) pattern of profunctor monads that can do bidirectional things, basically a question-answer free monad
This is useful if you need bidirectional things like parse/pretty print, query/update, etc. The refinery library uses it, but Iām pretty sure Iāve seen it in some serialization libraries as well.
There are also variants on a bunch of monads like adding codensity on top or tricks like āa smart view in datatypesā which can really help performance and for which an abstract view on monads can help.