Given a function
def f(i: I) : S => S
I would like to write a pretty common combinator g
def g(is : Seq[I], init: S) : S
The easy implementation uses only classic scala
def g(is : Seq[I], init: S) : S =
is.foldLeft(init){ case (acc, i) => f(i)(acc) }
I tried to use Foldable but I encountered a compilation issue.
import cats._
import cats.Monoid
import cats.implicits._
def g(is : Seq[I], init: S) : S =
Foldable[List].foldMap(is.toList)(f _)(init)
The error is
could not find implicit value for parameter B: cats.Monoid[S => S]
I succeeded with State
import cats.data.State
import cats.instances.all._
import cats.syntax.traverse._
def g(is : Seq[I], init: S) : S =
is.toList.map(i => State.modify(f(i))).sequenceU.runS(init).value
I have some questions :
Monoid for endomorphism in catsimport statements together ? Is there a trick to find the right import easily ?State a too powerful abstraction in this case ?[update] I've found a workaround for 1.
type Endo[S] = S => S
def g(is : Seq[I], init: S) : S
= Foldable[List].foldK[Endo, S](dirs.toList.map(f _))
But I still a foldMapK to avoid boilerplate …
foldMap won't work here because your f is I => S => S, which doesn't match the signature of foldMap:
def foldMap[A, B](fa: F[A])(f: (A) ⇒ B)(implicit B: Monoid[B]): B
you'll need your A => B and B => B => B (the Monoid) separate. f already merged these two operations. Just use foldLeft.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With