如何用猫折叠一组内同胚

时间:2017-01-02 16:56:19

标签: scala functional-programming scala-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

我有一些问题:

  1. 猫的内胚胎是否有Monoid
  2. 当我同时使用所有import语句时,您能解释编译问题吗?有没有一个技巧可以轻松找到合适的导入?
  3. 在这种情况下,State是一个过于强大的抽象吗?
  4. 有更好的方法吗?
  5. [更新] 我找到了1的解决方法。

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

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

1 个答案:

答案 0 :(得分:3)

foldMap因为fI => S => S foldMap而无法与def foldMap[A, B](fa: F[A])(f: (A) ⇒ B)(implicit B: Monoid[B]): B 的签名相匹配,因此无法在此工作:

A => B

您需要将B => B => BMonoidf)分开。 foldLeft已合并这两项操作。只需使用typedef unsigned char BYTE; Bool CheckForSubnetParity( BYTE[] _In_ iPAddress1, BYTE[] _In_ iPAddress2, BYTE[] _In_ subNetMask ) { BYTE[] NetworkPrefix1 = new BYTE[4]; BYTE[] NetWorkPrefix2 = new BYTE[4]; Bool Result = true; for ( int x = 0; x < 4; x++) { NetworkPrefix1[x] = iPAddress1[x] && subNetMask[x]; NetworkPrefix2[x] = iPAddress2[x] && subNetMask[x]; if ( NetworkPrefix1[x] != NetworkPrefix2[x] ) { Result = false; } } return Result; }