简体   繁体   中英

Function in generic class

I have class Seq and I want to have method "multy" that adds number to List factors, but I want, that only Seq of Number types will have this method, for this example, val numbers should work with multy, and val strings shouldn't.

import scala.collection.mutable.ListBuffer

object Main extends App{
  val strings = new Seq("f", "d", "a")
  val numbers = new Seq(1,5,4,2)
  val strings2 = new Seq("c", "b")
  numbers.multy(5)
  strings.multy(5)
  val strings3 = strings2.concat(strings)
  println(strings3)
  println(numbers)
}


class Seq[T : Ordering] (initialElems: T*) {
  override def toString: String = elems.toString

  val factors = ListBuffer[Number](1)

  val elems = initialElems.sorted

  def concat(a:Seq[T]) = new Seq(a.elems ++ this.elems:_*)

  def multy[T <: Number](a:Number) = {
    factors += a;
  }
}

If you want scala.Int , scala.Long , scala.Double , etc to not be supported - because they don't extend Number - you can define method as

def multy(a: Number)(implicit ev: T <:< Number): Unit = {
  factors += a
}

However, considering that under the hood they could be extending Number (if the compiler, decides that it should compile them as objects and not as primitives), usage of a type class would work better:

trait IsNumber[T] {
  def asNumber(value: T): Number
}
object IsNumber {
  implicit def numbersAreNumbers[T <: Number]: IsNumber[T] = t => t

  implicit val intIsNumber: IsNumber[Int] = i => (i: Number)
  ... // the same for Long, Short, etc
}

which could be used in multy as evidence

def multy(a: Number)(implicit ev: IsNumber[T]): Unit = {
  factors += a
}

and as normal type class in code that would need that knowledge for something:

def doSomethingWithElements(implicit isNumber: IsNumber[T]) = {
  elems.map(isNumber.asNumber).toList // List[Number]
}

This would support both java.lang.* Number s as well as Scala's numbers definitions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM