Use Lens.Family.LensLike 'as setter and receiver in state calculations
I would like to use the same lens as setter and getter inside stateful computation. And it looks like GHC can't infer generic type for Functor f.
import Lens.Family
import Lens.Family.State
import Control.Monad.State
-- | Run computation inside modified state
with :: Functor f => LensLike' f s a -> a -> State s b -> State s b
with lens value comp = do
value' <- use lens
lens .= value
res <- comp
lens .= value'
return res
So my question is, is it possible to achieve this behavior, or use separate lenses for the setter and getter? Thank!
source to share
A couple of options here. First, you can use RankNTypes so that each "call site" can use a different Functor instance, after which you can use LensLike "as both a receiver and a setter:
with :: (forall f. Functor f => LensLike' f s a) -> a -> State s b -> State s b
Second, and probably better, use a type Lens'
that is already existential, which allows it to be used as both a getter and a setter.
with :: Lens' s a -> a -> State s b -> State s b
You must allow the Functor to vary from a "call site" to a site, as the choice of a particular Functor is what changes the lens to getter or setter. The identity functor is used for customization, the Const functor is used to get it.
source to share