Effects

Extensible (or algebraic) effects are cool, but I don't want to get into depth here and equally I cannot because I am too dumb. The jist of them is instead of a fixed ordering of monads which you can add MonadFoo constraints to ala mtl:

f :: (MonadIO m, MonadBar m) => m a

You instead write GADTs with some type wizardry to achieve the same thing as typeclasses. The major advantage is that you can interpret these in multiple different ways (consider a logging effect that can be chosen to be viewed as an IO computation, or a pure ignore effect) and you don't need to deal with the O(n^2) instance problem:


data Bar m a where
  Log :: String -> Bar m ()
  SomethingElse :: Bool -> Int -> Bar m a

runBarAsIO :: ...

runBarAsPure :: ...

Why effects and not mtl?

The main reason is because effect frameworks are cool.