【问题标题】:Is the Writer Monad effectively the same as the State Monad?作家单子实际上与状态单子相同吗?
【发布时间】:2014-07-19 12:32:27
【问题描述】:

有一个很棒的教程here 似乎向我表明 Writer Monad 基本上是一个特殊情况的元组对象,它代表 (A,B) 执行操作。 writer 在左侧累积值(即 A),并且 A 具有相应的 Monoid(因此它可以累积或改变状态)。如果 A 是一个集合,那么它会累积。

State Monad 也是一个处理内部元组的对象。它们都可以是 flatMap'd、map'd 等。操作对我来说似乎是一样的。它们有何不同? (请回复一个 scala 示例,我不熟悉 Haskel)。谢谢!

【问题讨论】:

    标签: scala monads scalaz state-monad writer-monad


    【解决方案1】:

    tl;dr 状态是读写,而 Writer 是,嗯,只写。

    通过 State,您可以访问之前存储的数据,并且可以在当前计算中使用这些数据:

    def myComputation(x: A) =
      State((myState: List[A]) => {
            val newValue = calculateNewValueBasedOnState(x,myState)
            (log |+| List(newValue), newValue)
      })
    

    使用 Writer,您可以将数据存储在您无权访问的某个对象中,您只能写入该对象。

    【讨论】:

    • 另一个答案似乎表明 Writer 允许在最后读取累积值 1 次:in that it doesn't allow you to read the accumulated state (until you cash out at the end)。积累一些价值但永远无法阅读它有什么意义?
    • @RăzvanFlaviusPanda 我认为记录器是编写器的标准示例,在这种情况下,您想要写入文件或第三方系统,而程序的其余部分不应该关心或访问日志。
    【解决方案2】:

    您认为这两个 monad 密切相关的直觉是完全正确的。不同之处在于Writer 受到更多限制,因为它不允许您读取累积状态(直到您最后兑现)。对Writer 中的状态唯一可以做的就是在末尾添加更多内容。

    更简洁地说,State[S, A]S => (S, A) 的一种包装器,而Writer[W, A](W, A) 的包装器。

    考虑Writer的以下用法:

    import scalaz._, Scalaz._
    
    def addW(x: Int, y: Int): Writer[List[String], Int] =
      Writer(List(s"$x + $y"), x + y)
    
    val w = for {
      a <- addW(1, 2)
      b <- addW(3, 4)
      c <- addW(a, b)
    } yield c
    

    现在我们可以运行计算了:

    scala> val (log, res) = w.run
    log: List[String] = List(1 + 2, 3 + 4, 3 + 7)
    res: Int = 10
    

    我们可以用State做同样的事情:

    def addS(x: Int, y: Int) =
      State((log: List[String]) => (log |+| List(s"$x + $y"), x + y))
    
    val s = for {
      a <- addS(1, 2)
      b <- addS(3, 4)
      c <- addS(a, b)
    } yield c
    

    然后:

    scala> val (log, res) = s.run(Nil)
    log: List[String] = List(1 + 2, 3 + 4, 3 + 7)
    res: Int = 10
    

    但这有点冗长,我们还可以很多State做一些我们用Writer做不到的事情。

    所以这个故事的寓意是你应该尽可能使用Writer——你的解决方案会更干净、更简洁,并且你会因为使用了适当的抽象而感到满意。

    不过,Writer 通常不会为您提供所需的全部功能,在这种情况下,State 会等着您。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 2019-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      • 2019-12-13
      相关资源
      最近更新 更多