Probably they in fact mean Freer monad (paper, package) which are, as far as I understand, basically same thing as monad transformers with slightly another interface and having some some part of their implementation shared.
It has only one monadic type Eff r v
, where r
is a magical type which, as far as I understand, is a heterogenous list of stored data. To add a new transformer, you only need to define its core logic, and you don't have to define any new instances.
This is, for example, how much is needed to define State (the code is copypasted from package and subject to its license, BSD-3-Clause):
data State s v where
Get :: State s s
Put :: !s -> State s ()
get :: Member (State s) r => Eff r s
get = send Get
put :: Member (State s) r => s -> Eff r ()
put s = send (Put s)
runState :: Eff (State s ': r) w -> s -> Eff r (w,s)
runState (Val x) s = return (x,s)
runState (E u q) s = case decomp u of
Right Get -> runState (qApp q s) s
Right (Put s') -> runState (qApp q ()) s'
Left u' -> E u' (tsingleton (\x -> runState (qApp q x) s))
I'm not sure if this way offers any practical advantage over monad transformers, as they are already written.