Bluefin compared to effectful [video]

Looking at your local example, I’m actually confused about what it is supposed to do. The local I know allows you to locally alter the value that is read by the reader, which is nicely captured by its usual type signature local :: MonadReader r m => (r -> r) -> m a -> m a, but in your case you don’t seem to alter anything.

I think local should be good enough to show the workings of higher order effects. MonadReader in mtl does have local as a higher order operation that you can overload with your own instance. For example, you can choose not to apply the function:

newtype R r a = R (r -> a) deriving Functor deriving (Applicative, Monad) via ... 

instance MonadReader r (R r a) where
   ...
   local _ x = x

This handler changes the meaning of all uses of local in all existing programs written in the overloaded mtl style.

Can you define a local operation that allows you to delay the choice of whether or not to apply the context-modifying function to the time when the user applies the handler?

(This case is indeed a bit too simple, because I guess you could simply add a boolean in the record to indicate whether or not to apply the function, but what if someone comes around later and wants some different kind of behavior, like applying the function n times? You could change the boolean to a natural number, but does that capture all possible behaviors? I hope you can agree that a solution like that won’t work for all higher order operations.)

3 Likes