使用Scala中的单个函数将列表和向量中的int元素求和

时间:2019-05-09 16:09:15

标签: scala

如何使此代码起作用?

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

我想传递一个通用数据类型(Vector / List [Int]),并使用所描述的签名和代码结构来获取其元素的总和。

此刻我得到:

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

Scalafiddle

3 个答案:

答案 0 :(得分:3)

具体错误在这里:

val inst = new MyAddable

应该是

val inst = new MyAddable[Int]()

MyAddable是通用的,但是您没有指定类型,因此它假设Nothing,因此是错误消息。

答案 1 :(得分:2)

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 :(得分:1)

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

对于地图而言,这变得更加复杂