Some libraries, like lens, provide functions that are meant for use in MTL transformer stacks. Example:
http://hackage.haskell.org/package/lens-4.17/docs/Control-Lens-Setter.html#g:5
If Eff had an instance for MonadState, then I could use those Lens functions without having to rewrite them using the put and get from Control.Monad.Freer.State - it would happen automatically.
I have spent a number of days on this, but my instance manipulation skills are not the greatest, so I ended up with something like this:
instance MTL.MonadState s (Eff (State s ': effs)) where
get = get
put = put
instance {-# OVERLAPPABLE #-} MTL.MonadState s (Eff effs) => MTL.MonadState s (Eff (eff ': effs)) where
get = MTL.get
put = MTL.put
-- single actions that uses MTL and Eff values together without wrapping/unwrapping newtypes
action :: Eff (State Bool ': effs) ()
action = do
b <- MTL.get
put $ not b
ranAction :: Eff effs ((), Bool)
ranAction = runState True action
I also tried a solution involves defining an instance for a newtype wrapping Eff and using the constraints library to unsafely deduce MonadState s (Eff effs) from Member (State s) effs, but I had to use explicit TypeApplication to get it to work. I can post the code for that if you think that avenue is more likely where you would want to go with this.
A third possibility would be using something from the reflection package to provide the instance at runtime, but I haven't explored that.
I have only been playing around with
TL;DR: I don't know the best way to do this, but I think this library can provide something helpful for this use case.
Some libraries, like lens, provide functions that are meant for use in MTL transformer stacks. Example:
http://hackage.haskell.org/package/lens-4.17/docs/Control-Lens-Setter.html#g:5
If
Effhad an instance forMonadState, then I could use those Lens functions without having to rewrite them using theputandgetfrom Control.Monad.Freer.State - it would happen automatically.I have spent a number of days on this, but my instance manipulation skills are not the greatest, so I ended up with something like this:
I also tried a solution involves defining an instance for a newtype wrapping Eff and using the constraints library to unsafely deduce
MonadState s (Eff effs)fromMember (State s) effs, but I had to use explicit TypeApplication to get it to work. I can post the code for that if you think that avenue is more likely where you would want to go with this.A third possibility would be using something from the
reflectionpackage to provide the instance at runtime, but I haven't explored that.I have only been playing around with
TL;DR: I don't know the best way to do this, but I think this library can provide something helpful for this use case.