什么时候应该使用 MonadState 镜头组合器?

When should I use MonadState lens combinators?

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

但是我不明白这种状态与像 assign. Especially when lens can operate on multiple targets. Also, there are simpler functions like set 这样不需要状态的镜头组合器中使用的状态有何关系。

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

我建议您阅读这篇关于在 MonadState 中使用镜头的优秀博客 post。它为您提供了 Haskell 多么棒的示例。

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

关于您关于 assignset 之间区别的问题:assign 只是在 MonadState 内部运行的 set 的一个版本。而已。您可以通过实施观察到这一事实。

让我举几个例子。

您可以使用 set 设置(抱歉重复)某些 object 的某些 field:

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)

就是这样。 assignset 的行为类似,只是它将镜头应用于 state.