
Matt wrote:
The mtl technique subsumes the free monad technique. if you have a term: getCurrentTime :: MonadClock m => m UTCTime
The relationship between MTL and Free(r) monad approaches is filled with confusion, as you message has just demonstrated. There is nothing specific to MTL in writing the constraints like MonadClock. There is absolutely nothing that prevents you from defining instance Member ClockEffect r => MonadClock (Eff r) or similar with Free monads, instance MonadClock (Free CurrentTimeF) (which are less efficient, compose less well and require the boilerplate of writing functor instances). In short, defining constraints like MonadClock, MonadState etc. is not specific to any approach to effects. The difference between the monad transformer and Free monad is how you build types that satisfy the MonadClock etc. constraint. In MTL, you build by applying monad transformer to a suitable base monad. In Free monad, you define functors like CurrentTimeF and then build the Free monad. In Freer monad approach, your example getCurrentTime will look like getCurrentTime :: Member ClockEffect r => Eff r UTCTime which looks quite like getCurrentTime :: MonadClock m => m UTCTime in your example. Therefore, there is usually no need to define a separate MonadClock class. But nothing stops you from doing that.