semigrupos resueltos propiedades operaciones monoides grupo finitas estructuras ejercicios demostracion definicion binarias anillo algebraicas abeliano scala functional-programming scalaz scalaz7

scala - resueltos - ¿Por qué la Lista es un Semigrupo pero Seq no?



operaciones binarias y sus propiedades pdf (1)

Soy bastante nuevo en Scalaz y estoy tratando de descubrir por qué funciona el siguiente código:

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

pero esto no ...

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]]()

Veo el Mapa implícito para Semigroup, pero no veo el de List o Seq.

Preguntas de pareja:

  1. ¿Dónde está el implícito para ListSemigroup?
  2. ¿Por qué no hay uno para Seq?

Entonces, en Scalaz 7 hay una función implícita de List to Monoid que te devuelve un Monoid[List[A]] . SemiGroup extiende SemiGroup por lo que tenemos la lista cubierta.

Seq no recibe este tratamiento especial. No hay conversión implícita de Seq a Semigroup o Semigroup . Existe un IndexedSeq implícito a IndexedSeq , pero esto no nos ayuda.

¿Por qué no hay uno para Seq? No lo sé. Quizás Seq viola algunas leyes de monoids / semigroups por lo que no hay conversión. Parece que hubo problemas con Seq en Scalaz 6, por lo que eliminaron algunas funciones: https://groups.google.com/forum/?fromgroups=#!searchin/scalaz/Seq/scalaz/Deaec1H11W4/gYFSquXjTzYJ

ACTUALIZAR

Mirando el scala doc se vuelve más aparente por qué los scalaz se fueron de esta manera. List hereda LinearSeq que hereda Seq. IndexedSeq hereda Seq. Si tuvieran que proporcionar un semigrupo para Seq, podría anular cualquier otro semigrupo en IndexedSeq o LinearSeq y perder ventajas de rendimiento entre los dos. Si observa las firmas scalaz para anexar, puede ver que aprovechan estas diferencias de rendimiento:

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 }

Si profundizamos, vemos que Seq solo implementa ++ que tiene un peor rendimiento en listas que ::: para operaciones de adición. Entonces, para responder a su segunda pregunta, desempeño. Si Scalaz implementó semigroup para Seq, lo más probable es que conduzca a un rendimiento ambiguo, ya que solo podría optimizar para indexado. Iterable tiene el mismo problema.