如何用猫折叠一组内同胚

Yan*_*san 5 functional-programming scala scala-cats

给定一个功能

def f(i: I) : S => S
Run Code Online (Sandbox Code Playgroud)

我想写一个非常常见的组合器 g

def g(is : Seq[I], init: S) : S
Run Code Online (Sandbox Code Playgroud)

简单的实现仅使用经典scala

def g(is : Seq[I], init: S) : S = 
  is.foldLeft(init){ case (acc, i) => f(i)(acc) }
Run Code Online (Sandbox Code Playgroud)

我尝试使用,Foldable但我遇到了编译问题.

import cats._
import cats.Monoid
import cats.implicits._
def g(is : Seq[I], init: S) : S = 
  Foldable[List].foldMap(is.toList)(f _)(init)
Run Code Online (Sandbox Code Playgroud)

错误是

could not find implicit value for parameter B: cats.Monoid[S => S] 
Run Code Online (Sandbox Code Playgroud)

我成功了 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
Run Code Online (Sandbox Code Playgroud)

我有一些问题 :

  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 _))
Run Code Online (Sandbox Code Playgroud)

但我还是foldMapK要避免样板...

Rea*_*onk 3

foldMap在这里不起作用,因为你的fis I => S => S,它与 的签名不匹配foldMap

\n\n
def foldMap[A, B](fa: F[A])(f: (A) \xe2\x87\x92 B)(implicit B: Monoid[B]): B\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n