我是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]]()
我看到Semigroup隐含了Map,但我看不到List或Seq的那个。
夫妻问题:
答案 0 :(得分:29)
因此,在Scalaz 7中有一个implicit List
to Monoid
function可以返回Monoid[List[A]]
。 Monoid
扩展了SemiGroup
,因此我们覆盖了列表。
Seq
没有得到这种特殊待遇。没有从Seq
到Monoid
或Semigroup
的隐式转换。有一个implicit IndexedSeq
to Monoid
,但这对我们没有帮助。
为什么Seq不存在?我不知道。也许Seq违反了一些幺半群/半群的定律,所以没有转换。似乎Scalaz 6中的Seq存在问题,因此他们删除了一些功能: https://groups.google.com/forum/?fromgroups=#!searchin/scalaz/Seq/scalaz/Deaec1H11W4/gYFSquXjTzYJ
<强>更新强>
看看scala文档,为什么scalaz人会这样做更加明显。 List继承了继承Seq的LinearSeq。 IndexedSeq继承了Seq。如果它们为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实现了semigroup,那么很可能会导致模糊的性能,因为你只能为索引进行优化。 Iterable也有同样的问题。