6

I have seen this post which gives sort of an abstract characterization of what free monads are. I also understand what Monad Transformers are, and I understand (to some extent) why they could be useful.

I am not aware of what free monads are used for or what monad transformer libraries are. I have also heard about the mtl vs free monad debate, but I am not sure what it is, as I cannot find any discussion on the internet about this.

Can somebody explain what is this controversy about?

  • 1
    Relevant opinionated reading: [*Free monad considered harmful*](https://markkarpov.com/post/free-monad-considered-harmful.html), by Mark Karpov. See also [this discussion thread about that blog post](https://www.reddit.com/r/haskell/comments/72th9v/free_monad_considered_harmful/). – duplode May 26 '18 at 12:25

1 Answers1

1

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.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
max630
  • 8,762
  • 3
  • 30
  • 55
  • There is at least one practical advantage: you can have two implementations of a single collection of effects, e.g. one which is used in the production code and one which is a simplified mockup to use for testing. – Daniel Wagner May 26 '18 at 13:15
  • Doesn't mtl provide `MonadState` class etc.? – max630 May 26 '18 at 13:32
  • Sure, but `MonadIO` in particular is very difficult to mock. – Daniel Wagner May 26 '18 at 14:51
  • One advantage of the freer monad is that you can have multiple implementations of the same monadic actions, and choose which one you want dynamically. – MathematicalOrchid May 29 '18 at 10:09
  • @MathematicalOrchid this is very nice to hear. Probably it would make sense to describe it with example as another answer, I'd be interested to read too. – max630 May 29 '18 at 12:13
  • @max630 It's interesting, but I'm not sure how relevant it is to the original question. – MathematicalOrchid May 29 '18 at 14:43
  • @DanielWagner, @max360: One way to solve this is to create a wrapper monad around the `IO` monad, which is used in place of `IO` but only expose some of the things from `IO` that are used by the application. Then it is easy to create a mock of the wrapper monad. – Lii Jun 01 '18 at 11:50