5

给定一个函数

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

我有一些问题 :

  1. Monoid猫的内同性是否存在
  2. 当我import一起使用所有语句时,你能解释编译问题吗?有什么诀窍可以轻松找到正确的导入吗?
  3. 在这种情况下是State一个过于强大的抽象吗?
  4. 有没有更好的办法 ?

[更新] 我找到了 1 的解决方法。

type Endo[S] = S => S
def g(is : Seq[I], init: S) : S 
  = Foldable[List].foldK[Endo, S](dirs.toList.map(f _))

但我还是foldMapK要避免样板……</p>

4

1 回答 1

3

foldMap在这里不起作用,因为您的fisI => S => S与 的签名不匹配foldMap

def foldMap[A, B](fa: F[A])(f: (A) ⇒ B)(implicit B: Monoid[B]): B

您需要将您的A => BB => B => B(the Monoid) 分开。f已经合并了这两个操作。只需使用foldLeft.

于 2017-01-02T20:18:14.457 回答