3

我正在寻找一个版本,.~它接受一个包含在 Monad 中的值并返回一个 Monad。例如:

(0, 1) & _1 .~ 100 = (100,1)

假设.~~会:

(0, 1) & _1 .~~ return 100 = return (100,1)

虽然不难定义,但它是否已经在 Lens 包中的某个地方定义了?

4

1 回答 1

4

我不知道一个操作员是否完全像这样,但是通过一些“微小”的调整,这基本上就是镜头的原始应用所做的。调整如下:

  • 您使用修改功能而不仅仅是设置值。
  • Monad需要成为一个Functor,几乎所有的都是。(这在 GHC 7.10 中是强制性的,但在 7.8 中还没有。)

所以你可以这样做:

Prelude Control.Lens> (0,1) & _1 (const (Just 100))
Just (100,1)
Prelude Control.Lens> (0,1) & _1 (const [100])
[(100,1)]
Prelude Control.Lens> (0,1) & _1 (const [100,200])
[(100,1),(200,1)]

甚至适用于Traversals

Prelude Control.Lens> (0,1) & both (const [100,200])
[(100,100),(100,200),(200,100),(200,200)]

如果您还想要一个运算符,则该%%~运算符已被定义,但它本质上是一个受类型限制的同义词id

Prelude Control.Lens> (0,1) & _1 %%~ const (return 100) :: Either () (Int,Int)
Right (100,1)

最后,尽管您确实说它很简单,但您的.~~运算符(我认为.%~如果它实际上在逻辑上是或类似的lens)可以定义为

Prelude Control.Lens> let (.~~) = (. const)
Prelude Control.Lens> (0,1) & _1 .~~ return 100 :: Either () (Int,Int)
Right (100,1)
于 2014-10-27T17:48:47.573 回答