Как работает ниже для понимания? - PullRequest
0 голосов
/ 04 июля 2018

Я пытался решить упражнения в https://github.com/dehun/learn-fp/blob/master/src/test/scala/learnfp/monad/WriterTest.scala. В настоящее время я не могу понять, как работает приведенный ниже код, особенно строки с номерами 20, 22 и 24. WriterString не имеет метода map , Кроме того, какая польза от _?

"writer monad" should {
    "work" in {
      val s : Int = 3
      type WriterString[A] = Writer[List[String], A];
      {
        for {
          x <- 1.pure[WriterString]
          _ <- tell(List("een"))
          y <- 2.pure[WriterString]
          _ <- tell(List("twee"))
          z <- 3.pure[WriterString]
          _ <- tell(List("drie"))
      } yield (x, y, z) }.run() shouldBe (List("een", "twee", "drie"), (1, 2, 3))
    }

Ответы [ 2 ]

0 голосов
/ 04 июля 2018
for {
  a <- A
  b <- B
  c <- C
} yield (a,b,c)

переводится как

A.flatMap { a =>
  B.flatMap { b =>
     C.map { c => (a,b,c) }
  }
}

последняя операция переводится в map (или foreach, если вы не yield результат), все операции перед ним - в flatMap. Операции являются вложенными (следующая <- означает следующую вложенную операцию).

Аналогично if s переводится в withFilter.

_ означает, что вы игнорируете значение (вам нужно присвоить параметру flatMap / map что-то, но вы можете решить не использовать его).

0 голосов
/ 04 июля 2018

Если вы хотите использовать для понимания (например, с помощью intellij или от руки) вы получите

  {
    1.pure[WriterString]
      .flatMap(
        x =>
          tell(List("een")).flatMap {
            case _ =>
              2.pure[WriterString]
                .flatMap(
                  y =>
                    tell(List("twee")).flatMap {
                      case _ =>
                        3.pure[WriterString]
                          .flatMap(z => tell(List("drie")).map { case _ => (x, y, z) })
                  }
                )
        }
      )
  }.run()

Примечание _ (подчеркивание) в кейсах, они в основном означают, что мы не заботимся о значении. И, в частности, здесь нам все равно, потому что tell возвращает Writer со значением типа Unit.

def tell[W](m:W)(implicit monoid:Monoid[W]):Writer[W, Unit] = ???

А tell происходит от импорта import learnfp.functor.Writer._

WriterString - это псевдоним типа для Writer, который можно преобразовать в FunctorOps (который, вероятно, имеет метод map) - https://github.com/dehun/learn-fp/blob/master/src/main/scala/learnfp/functor/Writer.scala#L16

...