Luk*_*con 5 haskell haskell-lens
我正在寻找类似于以下类型的函数:
Monad m => (a, b) -> (b -> m c) -> m (a, c)
Run Code Online (Sandbox Code Playgroud)
在我看来,它是bind(>>=)和镜头操作的一些组合.
我知道我可以在绑定后用模式匹配来解决这个问题,但我的直觉告诉我,通过利用镜头来编写这个"更简单"的方法.
有没有这样的手术?
这绝对是镜头.monad实际上只是一点点分心,因为你需要的只是一个仿函数:
changesecond (a, b) f = fmap (a,) (f b)
Run Code Online (Sandbox Code Playgroud)
我很确定_2镜头可以用基本的镜头做出来,over但是我对图书馆还不太熟悉.
实际上不需要组合器.你可以写
changesecond pair f = _2 f pair
Run Code Online (Sandbox Code Playgroud)
您应该能够从Lens类型的一般定义中解决这个问题.
这个简单的例子展示了Van Laarhoven镜头结构的主题:
fmap的环境恢复的结果.Ed Kmett的lens图书馆以各种方式阐述了这一主题.有时它会加强仿函数约束.有时它会将函数概括为profunctor.在这种情况下Equality,它会删除仿函数约束.事实证明,相同的基本类型形状可以表达许多不同的想法.
你的功能只是forM = flip mapM,或者for = flip traverse如果你放松Monad约束Applicative.该Functor所走过的(,) a.
Prelude> let foo :: Applicative f => (a, b) -> (b -> f c) -> f (a, c); foo p k = traverse k p
Prelude> :t foo
foo :: Applicative f => (a, b) -> (b -> f c) -> f (a, c)
Prelude> foo (1,2) (\x -> [x,2*x])
[(1,2),(1,4)]
Run Code Online (Sandbox Code Playgroud)
(另外,正如dfeuer指出的那样,Applicative在这种特殊情况下你根本不需要.)