加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala Cats或Scalaz类型类scanLeft之类

发布时间:2020-12-16 18:06:55 所属栏目:安全 来源:网络整理
导读:我想知道在Cats或 Scalaz中是否有类型类提供这样的运算符: def scan[G[_],A,B](zero: B)(g: G[A],f: (A,B) = B):G[B] 或者,如果存在这样的运算符的某种数学定义(类似于Monad for bind / flatMap). 这个类型类的想法是将二进制函数应用于类型构造函数并获取
我想知道在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,这不是一半坏.如果你不是,你可能最好使用子类型进行泛化

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读