我不太清楚有没有与此类似的单一运算符,但是通过一些“微小”的调整,这基本上是镜头的原始应用。这些调整包括:
- 您需要使用修改函数而不仅仅是设置值。
- 您的
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)]
甚至可以与 遍历
一起使用:
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)
(.~~) = liftM3 (.~)
。但它的所有参数都必须是单子的,所以你可以这样做:return (0, 1) & return _1 .~~ return 100
。最好用一个do
块来定义它,如(.~~) l m x = do { v <- m; return $ x & l .~ v }
。 - bheklilrfmap
,如(.~~) l m x = fmap ((x &) . (l .~)) m
,而且它也更短。测试它,例如(0, 1) & _1 .~~ Just 1
,返回Just (1, 1)
。 - bheklilr