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