Monad transformers in Haskell have been completely under my radar until today.
I did some reading on them, and discovered that they seem to be the "right" types to use when you have a stack of monads.
For example, in GOOL we currently have many values with types like State GOOLState (repr (Program repr)). State is a monad and repr is a monad -- it is a "stack" of monads (well, GOOL doesn't actually constrain repr to be a Monad, but we only ever instantiate repr with monadic types, so I think we could add that constraint).
But monad transformers, like StateT, are used to combine monads into a single, new monad. So the above could be StateT GOOLState repr (Program repr). Using monad transformers should lead to cleaner code, because you are dealing with one monad (which has two effects) instead of two monads (each with one effect). So places where we currently have functions that start with on2StateValues (on2CodeValues (... or where we have nested do-notation could be simplified.
I'm just unsure how cleanly this would work for the functions where some parameters are State-reprs, some are just reprs with no state, and still others have state but are not reprs.
I doubt this should be a high priority for me, but maybe something we should change in the long term. But I'm curious what you think, @JacquesCarette.
I didn't head towards this as I didn't want to force repr to be a monad. But if it always is, de facto, then yes, this could simplify things. Indeed, low priority.
Monad transformers in Haskell have been completely under my radar until today.
I did some reading on them, and discovered that they seem to be the "right" types to use when you have a stack of monads.
For example, in GOOL we currently have many values with types like
State GOOLState (repr (Program repr))
.State
is a monad andrepr
is a monad -- it is a "stack" of monads (well, GOOL doesn't actually constrainrepr
to be aMonad
, but we only ever instantiaterepr
with monadic types, so I think we could add that constraint).But monad transformers, like
StateT
, are used to combine monads into a single, new monad. So the above could beStateT GOOLState repr (Program repr)
. Using monad transformers should lead to cleaner code, because you are dealing with one monad (which has two effects) instead of two monads (each with one effect). So places where we currently have functions that start withon2StateValues (on2CodeValues (...
or where we have nested do-notation could be simplified.I'm just unsure how cleanly this would work for the functions where some parameters are State-reprs, some are just reprs with no state, and still others have state but are not reprs.
I doubt this should be a high priority for me, but maybe something we should change in the long term. But I'm curious what you think, @JacquesCarette.
(I found this Stack Overflow discussion helpful for understanding the advantages of monad transformers vs. a stack of monads: https://stackoverflow.com/questions/38710154/why-are-monad-transformers-different-to-stacking-monads)