jor*_*an3 19 monads scala state-monad scalaz writer-monad
有一个伟大的教程在这里,这似乎暗示,我认为作家单子基本上是做代表的工作的特殊情况,元组对象(A,B).作者在左边积累了值(即A),并且A与它有相应的Monoid(因此它可以累积或改变状态).如果A是一个集合,那么它就会累积.
State Monad也是一个处理内部元组的对象.它们都可以是flatMap'd,map'd等等.这些操作对我来说都是一样的.他们有什么不同?(请用scala示例回复,我不熟悉Haskel).谢谢!
Tra*_*own 36
你对这两个单子密切相关的直觉是完全正确的.区别在于它Writer更加有限,因为它不允许您读取累积状态(直到您在结束时兑现).你可以用a状态做的唯一事情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
Run Code Online (Sandbox Code Playgroud)
现在我们可以运行计算了:
scala> val (log, res) = w.run
log: List[String] = List(1 + 2, 3 + 4, 3 + 7)
res: Int = 10
Run Code Online (Sandbox Code Playgroud)
我们可以做同样的事情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
Run Code Online (Sandbox Code Playgroud)
然后:
scala> val (log, res) = s.run(Nil)
log: List[String] = List(1 + 2, 3 + 4, 3 + 7)
res: Int = 10
Run Code Online (Sandbox Code Playgroud)
但这有点冗长,我们也可以做很多其他事情State,我们无法做到Writer.
因此,故事的寓意是你应该Writer随时使用- 你的解决方案将更清洁,更简洁,并且你会对使用适当的抽象感到满意.
但是,通常Writer不会给你所需的所有力量,并且在那些情况下State会等你.
| 归档时间: |
|
| 查看次数: |
1649 次 |
| 最近记录: |