我会在有状态计算中使用相同的镜头作为setter和getter。 似乎GHC无法推断出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
所以我的问题是,是否有可能实现这样的行为,还是应该使用单独的镜头作为制定者和吸气剂?谢谢!
答案 0 :(得分:5)
这里有几个选择。首先,您可以使用RankNTypes,以便可以在每个“呼叫站点”使用不同的Functor实例,随后您可以将LensLike'用作getter和setter:
with :: (forall f. Functor f => LensLike' f s a) -> a -> State s b -> State s b
其次,可能更好,是使用已经存在的Lens'
类型 - 允许同时用作getter和setter。
with :: Lens' s a -> a -> State s b -> State s b
您必须允许Functor从“呼叫站点”变为呼叫站点,因为选择特定的Functor会将镜头更改为getter或setter。 Identity Functor用于设置,Const functor用于获取。