abhi
abhi

Reputation: 41

how is flatMap working with custom monads

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

Answers (2)

Iva Kam
Iva Kam

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

1565986223
1565986223

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

Related Questions