0

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; } } 
3
  • What should multy do for types that are not supported? Commented May 7, 2020 at 11:40
  • scala.Int, scala.Double, etc are not subclasses of Number Commented May 7, 2020 at 11:42
  • My idea, is that "multy" wouldn't be supported Commented May 7, 2020 at 11:46

1 Answer 1

1

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.* Numbers as well as Scala's numbers definitions.

Sign up to request clarification or add additional context in comments.

3 Comments

If I need only scala Int, Double, Float to be for multy, what can I use instead AnyVal (because it contains boolean for example) def multy(a: Number)(implicit ev: T <:< AnyVal):
Why not just using the built in Numric typeclass?
Numeric doesn't expose method of casting to java.lang.Number that OP might want. It allows casting directly .toLong, .toDouble etc, which could change the value underneath. If this Number x Number semantics is not needed (I assume it is because factors are Numbers) and OP would be OK with factory: List[T] (empty if T is not Numeric) and appending to it only if T is Numeric, then yes, Numeric would be sufficient.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.