3

我会在有状态计算中使用与 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

所以我的问题是,是否有可能实现这种行为,或者我应该为 setter 和 getter 使用单独的镜头?谢谢!

4

1 回答 1

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

于 2014-08-07T14:12:46.093 回答