Scala Cats或Scalaz类型类scanLeft之类

前端之家收集整理的这篇文章主要介绍了Scala Cats或Scalaz类型类scanLeft之类前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想知道在Cats或 Scalaz中是否有类型类提供这样的运算符:

def scan[G[_],A,B](zero: B)(g: G[A],f: (A,B) => B):G[B]

或者,如果存在这样的运算符的某种数学定义(类似于Monad for bind / flatMap).

这个类型类的想法是将二进制函数应用于类型构造函数获取相同类型的构造函数,但使用不同的类型参数(二进制函数返回的相同类型).

我认为类似于ScanLeft的Scala标准库集合.

解决方法

可能的实施之一是与州进行交叉:

import cats._,data._,implicits._

def scan[G[_]: Traverse: Applicative: MonoidK,B](list: G[A],zero: B,f: (B,A) => B): G[B] = {
  def generate(a: A): State[B,B] =
    for {
      prev <- State.get[B]
      next =  f(prev,a)
      _    <- State.set(next)
    } yield next

  zero.pure[G] <+> list.traverse(generate).runA(zero).value
}

这类似于stdlib中的scanLeft for Vectors和Lists(但不是选项!),但需要相当多的类型类!不幸的是,stdlib scanLeft会预先设置初始元素,因此结果集合总是比原始元素大一个元素,并且没有单个类型类提供任何类似的操作.

如果你没有预先设置零,你在G [_]上需要的只是Traverse,这不是一半坏.如果你不是,你可能最好使用子类型进行泛化

猜你在找的Scala相关文章