как flatMap работает с кастомными монадами - PullRequest
0 голосов
/ 20 февраля 2020

Я новичок в scala и запутался с реализацией Монад. В приведенной ниже программе, когда выполняется «a <- g (3)», значение «a» равно 23, а не Writer, почему? что происходит за сценой? </p>

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)
}

Ответы [ 2 ]

2 голосов
/ 20 февраля 2020

Из scala документов for comprehension: https://docs.scala-lang.org/tutorials/FAQ/yield.html https://docs.scala-lang.org/tour/for-comprehensions.html

это не что иное, как синтактический c сахар для составления нескольких операций monadi c

Ваш вызов

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 в синтаксисе-сахаре

0 голосов
/ 20 февраля 2020

Существует универсальный c интерфейс для монад, предоставляемый библиотекой кошек:

https://typelevel.org/cats/typeclasses/monad.html

На этой странице do c вы можете найти, как эффективно и правильно создать свою собственную монаду. Кроме того, кошки имеют собственную монаду Writer, пример использования:

https://medium.com/@spearsear / simple-use-of-cats-writer-monad-4a1694556112

...