在程序员新学习函数式编程和完成Cats here的在线Scala练习的背景下,以下结果似乎令人费解:
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相同,只不过我们使用通用的monoid(
MonoidK[G]
)来获得Monoid[G[A]]
实例。
我不明白这种差异会如何导致上面看到的行为,在某种程度上,Option("three")
会忽略列表中的第三个元素(foldK
)。
有人可以解释一下吗?
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
这应该是解释的事情。我不知道这是出于意图,还是仅仅是对猫实例中不一致的偏差。