5

我目前的代码如下所示:

do
  x <- use foo
  foo <~ runFoo x

foo一个字段在哪里,Lens并且FoorunFoo :: MonadState m => Foo -> m Foo

我认为应该有一种方法可以在一行中执行此操作,但我找不到。我认为它应该有这样的评论:

(????) :: MonadState s m => Lens' s a -> (a -> m a) -> m a

问题:

  • 这样的组合器存在吗?如果是这样,那是什么?
  • 当我遇到这样的另一个问题时,搜索它的最佳方法是什么(即通常我会在 Hoogle 中输入它,但我没有运气好用镜头库做到这一点)
  • 这实际上是 Control.Monad 中的原始组合器吗?(如果这是 kleisli 箭的另一份工作,我会有点尴尬)
4

2 回答 2

1

lens没有现成的形式提供这样的组合器。如果不是runFoo您有一些g :: a -> a功能,您将能够使用(%=), 即 to overwhat useis to view,并简单地编写foo %= g。但是,您想要的功能涉及在获取和设置之间交错m引入的效果runFoo,这排除了这种简单的解决方案。

于 2021-03-16T22:41:48.507 回答
0

您要查找的函数的类型签名可疑地接近>>=,但第一个参数不同。

特别是,它看起来像use foo :: Monad m => m Fooand foo <~ runFoo :: Foo -> m Foo,所以你可以直接使用 bind as use foo >>= (\x -> foo <~ runFoo x)。可能有更简单/更短的方法,但我没有完整的代码可以玩。我想说坚持使用两行,如果它是一个足够常见的操作,那么为它定义你自己的组合器。

于 2013-09-03T12:50:34.537 回答