使用Lens.Family.LensLike'作为状态计算中的setter和getter

时间:2014-08-07 13:48:28

标签: haskell lenses

我会在有状态计算中使用相同的镜头作为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

所以我的问题是,是否有可能实现这样的行为,还是应该使用单独的镜头作为制定者和吸气剂?谢谢!

1 个答案:

答案 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用于获取。