Ответ 1
Итак, в Scalaz 7 существует неявная List
to Monoid
функция, которая возвращает вам Monoid[List[A]]
. Monoid
extends SemiGroup
, поэтому мы включили Список.
Seq
не получает этого специального лечения. Нет никакого неявного преобразования от Seq
до Monoid
или SemiGroup
. Существует неявный IndexedSeq
до Monoid
, но это не помогает нам.
Почему нет Seq? Я не знаю. Возможно, Seq нарушает некоторые законы моноидов/полугрупп, поэтому конверсия отсутствует. Похоже, были проблемы с Seq в Scalaz 6, поэтому они убрали некоторые функции: https://groups.google.com/forum/?fromgroups=#!searchin/scalaz/Seq/scalaz/Deaec1H11W4/gYFSquXjTzYJ
UPDATE
Глядя на документ scala, становится все более очевидным, почему люди скасаза пошли таким образом. List наследует LinearSeq, который наследует Seq. 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, это, скорее всего, приведет к неоднозначной производительности, поскольку вы сможете оптимизировать только индексирование. У Iterable такая же проблема.