1
votes

Somme des éléments int dans la liste et le vecteur en utilisant une seule fonction dans Scala

Comment faire fonctionner ce code?

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

Je veux passer un type de données générique (Vector / List [Int]) et obtenir une somme de ses éléments en utilisant les signatures et le code décrits structure.

En ce moment, je reçois:

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")

Scalafiddle


3 commentaires

Comment comptez-vous faire la somme des éléments d'une Liste de Doubles ou de Chaînes ou de Cartes , etc.? Voulez-vous le faire fonctionner pour tous les types de données numériques? ou pour tout type auquel vous pouvez définir une opération add ?


@ LuisMiguelMejíaSuárez Je veux le faire fonctionner pour Int . A modifié la question


Si vous voulez seulement additionner la séquence de Ints , pourquoi avez-vous besoin du A générique? Ou c'est votre addable pour Ints et il existe un autre addable pour Floats ?


3 Réponses :


2
votes
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")

0 commentaires

3
votes

L'erreur spécifique est ici:

val inst = new MyAddable[Int]()

qui devrait être

val inst = new MyAddable

MyAddable est générique mais vous ne spécifient pas de type, donc il suppose Rien , d'où le message d'erreur.


1 commentaires

Merci pour la réponse. Je lui ai donné un +. Cependant, j'ai marqué une autre réponse car elle a également corrigé l'erreur de suivi



1
votes
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")
This gets a little more complicated for Maps

0 commentaires