Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I explain the difference between fold and foldK?

In the context of a programmer newly learning functional programming and completing the online Scala Exercises for Cats here, the following result seems puzzling:

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")
}

I can follow the example for fold but not for foldK. The documentation for foldK says:

This method is identical to fold, except that we use the universal monoid (MonoidK[G]) to get a Monoid[G[A]] instance.

I don't understand how this difference would cause the behaviour seen above where somehow the third element in the list (Option("three")) is "ignored" for the foldK.

Can someone please explain?

like image 931
David Rawson Avatar asked Oct 22 '25 05:10

David Rawson


1 Answers

fold uses a Monoid[Option[A]] instance, and cats/kernel/instances/option.scala has following implementation for 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))
        }
    }

But foldK wants a MoinoidK[Option] instance and the answer for this difference is in implementation of combineK for Option,

If your look into cats.instances.OptionInstances, you will find following

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

This should be explain things. I don't know if this is intended or just an overlooked deviation towards in-consistency in cats instances.

like image 76
sarveshseri Avatar answered Oct 24 '25 21:10

sarveshseri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!