代码之家  ›  专栏  ›  技术社区  ›  David Rawson B Aristide

我如何解释fold和foldK的区别?

  •  2
  • David Rawson B Aristide  · 技术社区  · 6 年前

    在程序员新学习函数式编程和完成在线Scala猫练习的背景下 here

    import cats._
    import cats.implicits._
    
    object Foo {
    
      def main(args: Array[String]): Unit =
        println(Foldable[List].fold(List(None, Option("two"), Option("three"))))
        //Some("twothree")
        println(Foldable[List].foldK(List(None, Option("two"), Option("three"))))
        //Some("two")
    }
    

    我可以效仿 fold 但不是为了 foldK . 这个 documentation for foldK

    这个方法与fold相同,只是我们使用了泛幺半群( MonoidK[G] )得到一个 Monoid[G[A]]

    我不明白这种差异是如何导致上述行为的,不知何故,列表中的第三个元素( Option("three") )被“忽略”了 福克

    1 回复  |  直到 6 年前
        1
  •  4
  •   sarveshseri    6 年前

    fold 使用Monoid[Option[a]]实例,并且 cats/kernel/instances/option.scala 具有以下实现 Monoid[Option[A]].combine ,

    def combine(x: Option[A], y: Option[A]): Option[A] =
        x match {
          case None => y
          case Some(a) =>
            y match {
              case None => x
              case Some(b) => Some(A.combine(a, b))
            }
        }
    

    但是 foldK 想要一个 MoinoidK[Option] combineK 对于 Option

    如果你调查 cats.instances.OptionInstances ,你会发现

      def combineK[A](x: Option[A], y: Option[A]): Option[A] = x orElse y
    

    这应该解释一下。我不知道这是有意的还是仅仅是在猫的例子中被忽视的一致性偏差。