Как я могу объяснить разницу между Fold и FoldK? - PullRequest
0 голосов
/ 07 сентября 2018

В контексте того, что программист недавно изучил функциональное программирование и выполнил онлайн-упражнения 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. Документация для foldK гласит:

Этот метод идентичен складыванию, за исключением того, что мы используем универсальный моноид (MonoidK[G]), чтобы получить экземпляр Monoid[G[A]].

Я не понимаю, как это различие может вызвать поведение, описанное выше, когда третий элемент в списке (Option("three")) каким-то образом "игнорируется" для foldK.

Может кто-нибудь объяснить, пожалуйста?

1 Ответ

0 голосов
/ 07 сентября 2018

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

Это должно быть объяснением вещей. Я не знаю, предназначено ли это или просто пропущено отклонение к непоследовательности в случаях кошек.

...