¿Cómo hacer que este código funcione?

sealed abstract class Addable[A] {
  def sum(el: Seq[A]): A
}

class MyAddable[A]() extends Addable[A] {
  override def sum(el: Seq[A]): A = {
    el.sum

  }
}

val myvec = Vector(1, 2, 3)
val mylist = List(1, 2, 3)

val inst = new MyAddable

val res0 = inst.sum(mylist) // should return 6
val res1 = inst.sum(myvec)  // should return 6

println(s"res0 = $res0")
println(s"res1 = $res1")

Quiero pasar un tipo de datos genérico (Vector / List [Int]) y obtener una suma de sus elementos utilizando las firmas y la estructura del código descritas.

En este momento estoy obteniendo:

found   : immutable.this.List[scala.this.Int]
 required: Seq[scala.this.Nothing]

Scalafiddle

1
techkuz 9 may. 2019 a las 19:09

3 respuestas

La mejor respuesta
sealed abstract class Addable[A] {
  def sum(el: Seq[A]): A
}

class MyAddable[A: Numeric]() extends Addable[A] {
  override def sum(el: Seq[A]): A = {
    el.sum
  }
}

val myvec = Vector(1, 2, 3)
val mylist = List(1, 2, 3)

val inst = new MyAddable[Int]()

val res0 = inst.sum(mylist)
val res1 = inst.sum(myvec)

println(s"res0 = $res0")
println(s"res1 = $res1")
2
Daryl 9 may. 2019 a las 16:16

El error específico está aquí:

val inst = new MyAddable

Cual debería ser

val inst = new MyAddable[Int]()

MyAddable es genérico pero no está especificando un tipo, por lo que supone Nothing, de ahí el mensaje de error.

3
Tim 9 may. 2019 a las 16:17
import cats.{Semigroup}
import cats.implicits._

// Specify a generic Reduce Function. Use Contravariant parameter to support reduce on derived types   
trait Reduce[-F[_]] {
  def reduce[A](fa:F[A])(f:(A,A) => A):A
}    

object Reduce {      
  implicit val SeqReduce  = new Reduce[Seq] {
    def reduce[A] (data:Seq[A])(f:(A,A) => A ):A = data reduce f 
  }

  implicit val OptReduce  = new Reduce[Option] {
    def reduce[A] (data:Option[A])(f:(A,A) => A ):A = data reduce f
  }        
}

// Generic sum function
def sum[A:Semigroup, F[_]](container: F[A])(implicit red:Reduce[F]):A = {
  red.reduce(container)(Semigroup.combine(_,_))
} 

  val myvec   = Vector(1, 2, 3)
  val mylist  = List  (1, 2, 3)

  val mymap   = Map ( 1 -> "one",
                      2 -> "two",
                      3 -> "three"
                    )
  val myopt   = Some(1)

  val res0  = sum(myvec)
  val res1  = sum(mylist)
  val res2  = sum(myopt)      

  println(s"res0 = $res0")
  println(s"res1 = $res1")
  println(s"res2 = $res2")

Esto se vuelve un poco más complicado para Maps

1
Tampler 10 may. 2019 a las 12:43