Skip to content

Free Monad

Nick Ager edited this page Oct 8, 2017 · 4 revisions

Free monads let you decompose any impure program into a pure representation of its behavior and a minimal impure interpreter. Source: Purify code using free monads

As a counter from a comment in Dependency rejection:

I don't advocate the "free monad" style that's presently trendy in Scala-land because I find it unnecessarily complex. 90% of the purported advantages of free monads are already supported by simpler language features.

and:

The Haskell philosophy isn't about rejecting side effects outright - it's about measuring and controlling them. I wouldn't write tryAcceptComposition using IO. Instead I'd program to the interface, not the implementation, using an mtl-style class to abstract over monads which support saving and loading reservations.

where the code becomes:

class Monad m => MonadReservation m where
    readReservations :: ConnectionString -> Date -> m [Reservation]
    createReservation :: ConnectionString -> Reservation -> m ReservationId

tryAcceptComposition :: MonadReservation m => Reservation -> m (Maybe ReservationId)
tryAcceptComposition r = runMaybeT $ do
    reservations <- lift $ readReservations connectionString (date r)
    accepted <- MaybeT $ return $ tryAccept 10 reservations r
    lift $ createReservation connectionString accepted

also from A tale of two Monads: Free vs MTL:

What we learned is utilizing Free vs mtl is not universally good or bad. They are each fantastic abstractions and it really comes down to your use case. If your use case is going to end up building deeply nested graphs of Free data types then it probably isn’t for you. In the end we gained a lot clarity from prototyping with Free and a lot of performance from refactoring to mtl.

Clone this wiki locally