代码之家  ›  专栏  ›  技术社区  ›  abhishek_rathaur

下面的理解如何工作?

  •  0
  • abhishek_rathaur  · 技术社区  · 7 年前

    我试着解决 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 回复  |  直到 7 年前
        1
  •  1
  •   Eugene Platonov    7 年前

    如果你为了理解而设计(例如使用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()
    

    注释 _ (强调)在case子句中,它们基本上意味着我们不关心值。尤其是在这里我们不在乎因为 tell 返回一个writer Unit 类型值。

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

    告诉 来自进口 import learnfp.functor.Writer._

    WriterString 是的类型别名 Writer 可以转换为 FunctorOps (可能有 map 方法) https://github.com/dehun/learn-fp/blob/master/src/main/scala/learnfp/functor/Writer.scala#L16

        2
  •  1
  •   Mateusz Kubuszok    7 年前
    for {
      a <- A
      b <- B
      c <- C
    } yield (a,b,c)
    

    翻译成

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

    最后一个操作转换为 map (如果你不是 yield 在它之前的所有操作 flatMap . 操作是嵌套的(下一个 <- 表示下一个嵌套操作)。

    同样地 if 翻译成 withFilter .

    _ 意味着您正在忽略该值(您必须将flatmap/map的参数指定给某个对象,但您可能决定不使用它)。