镜头修改失败
Lens modifying with failure
在Control.Lens.Lens
中有一个函数
modifying :: MonadState s m => ASetter s s a b -> (a -> b) -> m ()
允许 MonadState
状态下镜头下的值通过纯函数 (a -> b)
.
进行转换
然而,我们可能希望允许转换函数在 m
中失败,要求它具有 (a -> m b)
.
类型
我在lens库里找过这样的功能,没找到,所以实现了:
modifyingM l f = use l >>= f >>= assign l
哪个有用,但我想知道镜头库中是否已经有一个函数可以做到这一点。
我没有看到类似的东西。 ASetter
已定义
type ASetter s t a b = (a -> Identity b) -> s -> Identity t
所以它的功能不够强大(而且 Setter
也做不到)。另一方面,事实证明 Lens
比必要的要强一些。那么,让我们考虑如何使用 Traversal
.
type Traversal s t a b =
forall f. Applicative f => (a -> f b) -> s -> f t
所以
Traversal s s a b =
forall f. Applicative f => (a -> f b) -> s -> f s
我们想要哪个Applicative
? m
似乎是显而易见的尝试。当我们通过遍历 a -> m b
时,我们返回 s -> m s
。伟大的!与 lens
一样,我们实际上只需要用户提供一个 ATraversal
,我们可以克隆它。
modifyingM
:: MonadState s m
=> ATraversal s s a b
-> (a -> m b) -> m ()
modifyingM t f = do
s <- get
s' <- cloneTraversal t f s
put s'
很好,因为它只遍历状态一次。
即使那样也太过分了,真的。最自然的其实是
modifyingM
:: MonadState s m
=> LensLike m s s a b
-> (a -> m b) -> m ()
modifyingM t f = do
s <- get
s' <- t f s
put s'
您可以将其直接应用于 Traversal
、Lens
、Iso
或 Equality
,或使用 cloneTraversal
、cloneLens
、cloneIso
或(在 lens-4.18
或更高版本中)cloneEquality
将其应用于单态变体。
在Control.Lens.Lens
中有一个函数
modifying :: MonadState s m => ASetter s s a b -> (a -> b) -> m ()
允许 MonadState
状态下镜头下的值通过纯函数 (a -> b)
.
然而,我们可能希望允许转换函数在 m
中失败,要求它具有 (a -> m b)
.
我在lens库里找过这样的功能,没找到,所以实现了:
modifyingM l f = use l >>= f >>= assign l
哪个有用,但我想知道镜头库中是否已经有一个函数可以做到这一点。
我没有看到类似的东西。 ASetter
已定义
type ASetter s t a b = (a -> Identity b) -> s -> Identity t
所以它的功能不够强大(而且 Setter
也做不到)。另一方面,事实证明 Lens
比必要的要强一些。那么,让我们考虑如何使用 Traversal
.
type Traversal s t a b =
forall f. Applicative f => (a -> f b) -> s -> f t
所以
Traversal s s a b =
forall f. Applicative f => (a -> f b) -> s -> f s
我们想要哪个Applicative
? m
似乎是显而易见的尝试。当我们通过遍历 a -> m b
时,我们返回 s -> m s
。伟大的!与 lens
一样,我们实际上只需要用户提供一个 ATraversal
,我们可以克隆它。
modifyingM
:: MonadState s m
=> ATraversal s s a b
-> (a -> m b) -> m ()
modifyingM t f = do
s <- get
s' <- cloneTraversal t f s
put s'
很好,因为它只遍历状态一次。
即使那样也太过分了,真的。最自然的其实是
modifyingM
:: MonadState s m
=> LensLike m s s a b
-> (a -> m b) -> m ()
modifyingM t f = do
s <- get
s' <- t f s
put s'
您可以将其直接应用于 Traversal
、Lens
、Iso
或 Equality
,或使用 cloneTraversal
、cloneLens
、cloneIso
或(在 lens-4.18
或更高版本中)cloneEquality
将其应用于单态变体。