为镜头寻找缺失的状态组合器
Posted
技术标签:
【中文标题】为镜头寻找缺失的状态组合器【英文标题】:Searching for missing State Combinator for Lens 【发布时间】:2013-09-06 04:58:01 【问题描述】:我目前的代码如下所示:
do
x <- use foo
foo <~ runFoo x
其中foo
是Lens
到Foo
字段和runFoo :: MonadState m => Foo -> m Foo
我认为应该有一种方法可以在一行中执行此操作,但我找不到。我认为它应该有这样的评论:
(????) :: MonadState s m => Lens' s a -> (a -> m a) -> m a
问题:
这样的组合器存在吗?如果有,那是什么? 当我遇到类似这样的另一个问题时,搜索它的最佳方法是什么(即通常我只会在 Hoogle 中输入这个,但我在镜头库中没有运气) 这实际上是 Control.Monad 中的原始组合器吗? (如果这是 kleisli 箭的另一份工作,我会有点尴尬)【问题讨论】:
【参考方案1】:lens 并没有以现成的形式提供这样的组合器。如果你有一些g :: a -> a
函数而不是runFoo
,你将能够使用(%=)
,即over
,就像use
是view
,并简单地写foo %= g
。但是,您想要的功能涉及在获取和设置之间交错由runFoo
引入的m
效果,这排除了这种简单的解决方案。
【讨论】:
【参考方案2】:您要查找的函数的类型签名可疑地接近 >>=
,但第一个参数不同。
特别是,它看起来好像use foo :: Monad m => m Foo
和foo <~ runFoo :: Foo -> m Foo
,所以你可以直接使用bind 作为use foo >>= (\x -> foo <~ runFoo x)
。可能有更简单/更短的方法,但我没有完整的代码可以玩。我会说坚持使用两行,如果它是一个足够常见的操作,那么为它定义你自己的组合器。
【讨论】:
除了对 Haskell 的do
表示法脱糖之外,您实际上还做了什么吗?此技术可用于组合do
语句中的任意两行。我想合并use
和(<~)
。以上是关于为镜头寻找缺失的状态组合器的主要内容,如果未能解决你的问题,请参考以下文章