Reputation: 41
I am new in scala and confused with Monads' implementation. In the below program when "a <- g(3)" is executed the value of 'a' is 23 and not Writer, why? what is happening behind the scene?
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)
}
Upvotes: 0
Views: 148
Reputation: 962
There's a generic interface for monads provided by cats library:
https://typelevel.org/cats/typeclasses/monad.html
In this doc page you can find how to efficiently and correctly create your own monad. Besides, cats feature their own Writer monad, example usage:
https://medium.com/@spearsear/simple-use-of-cats-writer-monad-4a1694556112
Upvotes: 0
Reputation: 6718
From scala docs for comprehension
: https://docs.scala-lang.org/tutorials/FAQ/yield.html https://docs.scala-lang.org/tour/for-comprehensions.html
it is nothing more than a syntactic sugar for composition of multiple monadic operations
Your call
for {
a <- g(3)
b <- f(a)
} yield b
gets de-sugared to:
g(3).flatMap { n =>
f(n)
}
The desugaring is applied on the evaluated result of g(3). You can look at this as:
writer: Writer = g(3) // evaluation of g(3)
writer.flatMap { n => // flatMap on Writer
here n is your value which is Int
...
So here n
in the de-sugared is equivaluent to a
in the syntax-sugar
Upvotes: 2