[英]How to fold a collection of endomorphism with cats
给定一个功能
def f(i: I) : S => S
我想写一个非常常见的组合g
def g(is : Seq[I], init: S) : S
简单的实现仅使用经典scala
def g(is : Seq[I], init: S) : S =
is.foldLeft(init){ case (acc, i) => f(i)(acc) }
我试图使用Foldable
但我遇到了编译问题。
import cats._
import cats.Monoid
import cats.implicits._
def g(is : Seq[I], init: S) : S =
Foldable[List].foldMap(is.toList)(f _)(init)
错误是
could not find implicit value for parameter B: cats.Monoid[S => S]
我成功地接受了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
我有一些疑问 :
Monoid
import
语句时,你能解释编译问题吗? 有没有一个技巧可以轻松找到正确的导入? State
是一个过于强大的抽象吗? [更新]我找到了1的解决方法。
type Endo[S] = S => S
def g(is : Seq[I], init: S) : S
= Foldable[List].foldK[Endo, S](dirs.toList.map(f _))
但我仍然是一个foldMapK
以避免样板...
foldMap
在这里不起作用,因为你的f
是I => S => S
,它与foldMap
的签名不匹配:
def foldMap[A, B](fa: F[A])(f: (A) ⇒ B)(implicit B: Monoid[B]): B
你需要你的A => B
和B => B => B
( Monoid
)分开。 f
已经合并了这两个操作。 只需使用foldLeft
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.