我何时应该使用MonadState镜头组合器?

时间:2016-08-27 18:49:21

标签: haskell lens

我了解MonadState s m让我能够获取和更新s

但我不了解这种状态如何与像assign这样的镜头组合器中使用的状态有关。特别是当镜头可以在多个目标上操作时。此外,还有更简单的函数,如set,不需要状态。

每个类似组合器的用例是什么?

1 个答案:

答案 0 :(得分:2)

我建议你阅读这篇关于在MonadState内使用镜头的优秀博文。它为您提供了令人敬畏的Haskell的例子。

http://www.haskellforall.com/2013/05/program-imperatively-using-haskell.html

关于assignset之间差异的问题:assign只是在set内运作的MonadState版本。就是这样。您可以通过实施来观察这一事实。

让我举几个例子。

您可以使用set设置(对不起重复)某些对象的某些字段

ghci> set _2 42 ([0.1, 0.2], 3)
([0.1,0.2],42)

如果您想使用assign,则需要在某个State上下文中调用此函数。例如,考虑下一个简单的函数:

assignMe :: Int -> StateT ([Double], Int) IO ()
assignMe x = do
    before <- get
    liftIO $ putStrLn $ "before assignment: " ++ show before
    assign _2 x
    after <- get
    liftIO $ putStrLn $ "after assignment: " ++ show after

如果您现在在ghci中调用此函数,您可以观察其执行结果:

ghci> execStateT (assignMe 42) ([0.1,0.2], 3)
before assignment: ([0.1,0.2],3)
after assignment: ([0.1,0.2],42)
([0.1,0.2],42)

那就是它。 assign只是表现得像set,除了它将镜头应用于状态