.~(Haskell)的一元版本

.~(Haskell)的一元版本,haskell,haskell-lens,Haskell,Haskell Lens,我正在寻找一个版本的~,它接受一个封装在Monad中的值并返回一个Monad。例如: (0,1)和~100=(100,1) 假设的~~将: (0,1)和_1.~~return 100=return(100,1) 虽然不难定义,但它是否已经在镜头包中的某个地方定义了呢?我不知道有哪一个操作符是这样精确地定义的,但通过一些“微小”的调整,这基本上就是镜头的原始应用所做的。调整如下: 您可以使用修改函数,而不仅仅是设置值 你的单子必须是一个函子,几乎所有的都是。(这在GHC 7.10中是强制性的,但

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

(0,1)和~100=(100,1)

假设的
~~
将:

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

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

我不知道有哪一个操作符是这样精确地定义的,但通过一些“微小”的调整,这基本上就是镜头的原始应用所做的。调整如下:

  • 您可以使用修改函数,而不仅仅是设置值
  • 你的
    单子
    必须是一个
    函子
    ,几乎所有的都是。(这在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)
最后,尽管你说它很简单,但是你的
~
操作符(我认为如果它实际在
镜头中,逻辑上应该是
%~
或类似的操作符)可以定义为

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

我不相信该操作符已经存在于镜头中,但您可以定义类似于
(.~)=liftM3(.~)
。但是它的所有参数都必须是一元的,所以您可以执行
return(0,1)&return\u 1.~~return 100
。最好用
do
块定义它为
(.~~)lmx=do{v一个更一般的形式是
fmap
(.~~)lmx=fmap((x&)(l.~)m
),而且它也更短。测试它为
(0,1)和.~Just 1
返回
Just(1,1)