如何将fclabels Lens提升为Monad?

时间:2015-12-08 09:51:10

标签: haskell monads lenses

我尝试使用fclabels更新一些旧代码,从v0.4更新为v2.0(lts-3.17),提升label / {{ 1}}到monad。旧代码是:

lens

所以我做的第一件事就是将{-# LANGUAGE TypeOperators #-} import Data.Record.Label import Control.Monad (liftM, liftM2) liftMLabel :: Monad m => a :-> b -> m a :-> m b liftMLabel l = label (liftM $ get l) (liftM2 $ set l) 更改为label,将lens更改为set

modify

这给出了以下编译器错误:

{-# LANGUAGE TypeOperators #-}
import Data.Label
import Control.Monad (liftM, liftM2)

liftMLabel :: Monad m => a :-> b -> m a :-> m b
liftMLens l = lens (liftM $ get l) (liftM2 $ modify l)

这是有道理的,给出了Expected type: (m b -> m b) -> m a -> m a Actual type: m (b -> b) -> m a -> m a 如何处理liftM2 lens函数的每个arg。

旧的fclabels使用setter函数来创建标签,该标签接受一个简单的值参数。 modify函数用于创建更新的fclabels镜头,它使用现有值进行修改,我明白为什么它也会对monadic参数进行操作。

我需要为修改功能执行一些额外的管道工作,我发现modify做了类似于我想要的事情,但我不清楚最好的方法是什么总的来说。

那么处理ap函数的好方法是什么,所以我可以匹配预期的类型?

1 个答案:

答案 0 :(得分:0)

为什么不用长篇大论来编写呢?

而不是试图用无点的方式一次性写出来?
liftMLens :: (Monad m) => a :-> b -> m a :-> m b
liftMLens l = lens (liftM $ get l) $ \f mx -> do
    x <- mx
    let v = get l x
    v' <- f $ return v
    return $ set l v' x

当然,如果你真的想要......那么你就可以对它进行编码 -