运维开发网

Scala map2与元组内部的元组(或者:如何做这个简单的事情,但更好?)

运维开发网 https://www.qedev.com 2020-07-29 14:51 出处:网络 作者:运维开发网整理
情况: 事件的流(RxScala),我们使用tumblingBuffer()进行批处理,然后构建完整的调试历史记录.最终我想要所有值的(Seq [T],Seq [T]),所以我创建了以下函数作为foldLeft的累加器: def tupleConcat[S](a: (Seq[S], Seq[S]), b: (Seq[S], Seq[S])) = (a._1 ++ b._1, a._2 ++ b._
情况:

事件的流(RxScala),我们使用tumblingBuffer()进行批处理,然后构建完整的调试历史记录.最终我想要所有值的(Seq [T],Seq [T]),所以我创建了以下函数作为foldLeft的累加器:

def tupleConcat[S](a: (Seq[S], Seq[S]), b: (Seq[S], Seq[S])) = (a._1 ++ b._1, a._2 ++ b._2)

现在,这对我来说,在阅读了Runar& amp;保罗在Scala中的函数式编程,因为它看起来非常像两个monoid实例的map2,但我仍然有点坚持如何正确地推广它.到目前为止,我认为它可能看起来像:

def tupleConcatSG[S](a: (S,S), b: (S,S))(implicit s: Semigroup[S]) = (a._1 |+| b._1, a._2 |+| b._2)

(但是我必须从我能收集到的东西中将我的Seq推广到IndexedSeq).

为了进一步推广到任何Applicative,我想我需要一个元组实例,它可能来自Shapeless?还是我错过了一些明显的东西?

编辑:我还应该补充一点,我试图避免拉链和解压缩,基于偏见的性能问题,但也许我不应该担心…(每个翻滚缓冲区的价值(Seq,Seq)将长约15,000,并且决赛(Seq,Seq)应该是数百万).

元组部分已经存在;在最坏的情况下,你将需要无形scalaz.你的tupleConcatSG很好(你可以使用:Semigroup糖而不是显式的隐含),但如果你想能够使用| |你需要使它成为一个Semigroup实例,并隐式可用:

implicit def tupleConcatSg[S: Semigroup] = new Semigroup[(S, S)] {
  def append(f1: (S, S), f2: (S, S)) = ...
}

我怀疑你真正的问题是scalaz不带有Seq的任何实例,只有IndexedSeq – 见Why is List a Semigroup but Seq is not?.但如果您不担心在列表中使用Seq的性能影响,您可以轻松编写自己的Monoid [Seq]:

implicit object SeqMonoid extends Monoid[Seq]{...}

我不确定你对任何申请人的进一步概括是什么意思 – 我们已经相当普遍了.如果你正在谈论获得像List [Writer [Vector [String],A]]这样的Applicative组合的Applicative实例,那应该会自动发生.

0

精彩评论

暂无评论...
验证码 换一张
取 消