Haskell中的.~的单子版本

3
我正在寻找一个接受Monad包装的值并返回一个Monad的.~版本。例如: (0, 1) & _1 .~ 100 = (100,1) 假设的.~~应该: (0, 1) & _1 .~~ return 100 = return (100,1) 虽然定义它并不难,但在Lens软件包中是否已经定义了它?

1
我不认为Lens中已经存在该运算符,但是你可以定义类似的东西,如 (.~~) = liftM3 (.~)。但它的所有参数都必须是单子的,所以你可以这样做:return (0, 1) & return _1 .~~ return 100。最好用一个 do 块来定义它,如 (.~~) l m x = do { v <- m; return $ x & l .~ v } - bheklilr
一个更一般的形式可以使用 fmap,如 (.~~) l m x = fmap ((x &) . (l .~)) m,而且它也更短。测试它,例如 (0, 1) & _1 .~~ Just 1,返回 Just (1, 1) - bheklilr
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)]

甚至可以与 遍历 一起使用:

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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接