为什么列表中的一个半群,但是序列是不是?(Why is List a Semigroup but S

2019-07-23 07:47发布

我是相当新的scalaz,我想弄清楚,为什么下面的代码工作:

import scalaz._
import Scalaz._
scala> Map[String,List[String]]() |+| Map[String,List[String]]()
res3: scala.collection.immutable.Map[String,List[String]] = Map()

但是这不...

import scalaz._
import Scalaz._
scala> Map[String,Seq[String]]() |+| Map[String,Seq[String]]()
<console>:14: error: value |+| is not a member of      scala.collection.immutable.Map[String,Seq[String]]
          Map[String,Seq[String]]() |+| Map[String,Seq[String]]()

我看到了地图隐含的半群,但我没有看到一个列表或序列。

夫妇的问题:

  1. 哪里是隐含的ListSemigroup?
  2. 为什么没有一个序列?

Answer 1:

所以,在Scalaz 7有一个隐含的List ,以Monoid功能 ,让你回来Monoid[List[A]] Monoid延长SemiGroup ,所以我们有清单覆盖。

Seq不会得到这个特殊的待遇。 有从没有隐式转换Seq ,以MonoidSemigroup 。 有一个隐含的IndexedSeqMonoid ,但这并不能帮助我们。

为什么没有一个序列? 我不知道。 也许SEQ违反幺/半群的一些规律,所以没有转换。 好像有在Scalaz 6所以他们已经删除了一些功能与序列是问题: https://groups.google.com/forum/?fromgroups=#!searchin/scalaz/Seq/scalaz/Deaec1H11W4/gYFSquXjTzYJ

UPDATE

纵观斯卡拉文档变得更加明显,为什么人们scalaz就这样。 表继承它继承序列LinearSeq。 IndexedSeq继承序列。 如果他们提供SEQ半群,它可以凌驾于IndexedSeq或LinearSeq以及两者之间松散的性能优势,任何其他半群。 如果你看一下scalaz签名追加你可以看到,他们利用这些性能差异优势:

https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/std/List.scala

  implicit def listMonoid[A]: Monoid[List[A]] = new Monoid[List[A]] {
    def append(f1: List[A], f2: => List[A]) = f1 ::: f2
    def zero: List[A] = Nil
  } 

https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/std/IndexedSeq.scala

implicit def ixSqMonoid[A]: Monoid[IxSq[A]] = new Monoid[IxSq[A]] {
    def append(f1: IxSq[A], f2: => IxSq[A]) = f1 ++ f2
    def zero: IxSq[A] = empty
  }

如果我们深入挖掘,我们可以看到,SEQ只实现++这对名单逊于性能:::用于追加操作。 因此,要回答你的第二个问题,性能。 如果scalaz实施半群为SEQ这很可能会导致模棱两可的性能,你会只能够优化索引。 可迭代有同样的问题。



文章来源: Why is List a Semigroup but Seq is not?