我是scala的新手,并对Monads的实现感到困惑。在下面的程序中,当执行“ a <-g(3)”时,“ a”的值为23而不是Writer,为什么?幕后发生了什么?
case class Writer(value:Int, log:String) {
def map(f:Int=>Int): Writer = {
Writer(f(value), log)
}
def flatMap(f:Int=>Writer): Writer = {
val temp = f(value)
Writer(temp.value, log+"...."+temp.log)
}
}
object Test extends App {
def f(value: Int):Writer = {
Writer(40+value, s"f has $value")
}
def g(value: Int):Writer = {
Writer(20+value, s"g has $value")
}
val result1 = for {
a <- g(3)
b <- f(a)
} yield b
println(result1)
val result2 = g(3) flatMap {
a => f(a).map(b=>b)
}
println(result2)
}
答案 0 :(得分:2)
从scala文档for comprehension
:https://docs.scala-lang.org/tutorials/FAQ/yield.html https://docs.scala-lang.org/tour/for-comprehensions.html
它仅是组成多个单子操作的语法糖
您的通话
for {
a <- g(3)
b <- f(a)
} yield b
被贬低为:
g(3).flatMap { n =>
f(n)
}
对g(3)的评估结果应用减糖。您可以将其视为:
writer: Writer = g(3) // evaluation of g(3)
writer.flatMap { n => // flatMap on Writer
here n is your value which is Int
...
因此,这里的n
与语法糖中的a
等价
答案 1 :(得分:0)
cats库为monad提供了一个通用接口:
https://typelevel.org/cats/typeclasses/monad.html
在此文档页面中,您可以找到如何有效而正确地创建自己的monad的方法。 此外,猫还具有自己的Writer monad,用法示例:
https://medium.com/@spearsear/simple-use-of-cats-writer-monad-4a1694556112