Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional methods of Scala generic classes with restrictions for type parameters

Tags:

generics

scala

I believe that a generic class may make one of its methods available only assuming that its type parameters conform to some additional restrictions, something like (syntax improvised on the spot):

trait Col[T] extends Traversable[T] {
    def sum[T<:Int] :T = (0/:this)(_+_)
}

I guess I could use implicit parameters as evidence... Is there a language feature for this?

like image 656
Turin Avatar asked Jul 22 '13 18:07

Turin


2 Answers

You can also use a type bound on the type parameter, which is enforced by an implicit argument:

trait Col[T] extends Traversable[T] {
    def sum(implicit ev: T <:< Int) :T = (0/:this)(_+_)
}

<:< is actually a class, expressed in infix notation, defined in Predef.scala and explained in many places, including here

<:< means 'must be a subtype of'

You can also use =:= 'must be equal to' and X <%< Y 'must be viewable as' (ie. there is an implicit conversion to X from Y)

For a more detailed explanation of type constraints, see this SO question.

like image 146
RealName Avatar answered Oct 20 '22 22:10

RealName


In this case you can only use an implicit parameter, as the type gets determined before the method call.

trait Col[T] extends Traversable[T] {
  def sum(implicit num: Numeric[T]) :T = ???
}

If the method you are calling would be parameterized, you could use context bounds, which are just syntactic sugar for the implicit parameter bound to the type parameter:

def foo[A](implicit ev: Something[A]) = ???

is equivalent to

def foo[A : Something] = ???
like image 26
drexin Avatar answered Oct 20 '22 21:10

drexin