Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I specialise a functions type parameters in Scala like I can with C++ template specialisation?

I want to write a function that behaves differently depending on its type parameter. A simple example of what I want is shown below:

def f[Int] = "I'm an int"
def f[Float] = "I'm a float"
def f[Burger] = "You want fries with that?"

Is this possible in Scala or do I need some kind of work around?

like image 519
BenP Avatar asked Jul 27 '12 02:07

BenP


3 Answers

Not directly; the usual way you'd do this in Scala is with a typeclass.

trait FAble[T] { def doF: String }
object FAble {
  implicit val fInt = new FAble[Int] { def doF = "I'm an int" }
  implicit val fFloat = new FAble[Float] { def doF = "I'm a float" }
  implicit val fBurger = new FAble[Burger] { def doF = "You want fries?" }
}

def f[T](implicit ev: FAble[T]) = ev.doF
// or
def f[T: FAble] = implicitly[FAble[T]].doF

It's a fair bit more verbose, but it has some advantages too -- the implicit instances can be computed (using implicit defs instead of vals), and there can be more than one instance for any given type, which lets you select behavior at by having different instances in scope at different points of the code.

The reason you can't do it the C++ way is that Scala generics do not involve code generation for the different type-parameters (@specialized aside, since it doesn't do what you want either). So it doesn't make sense to say "hey compiler, when you see an Int in that position, instead of generating the code you would from the generic template, use this specific code instead".

like image 123
RM. Avatar answered Oct 26 '22 09:10

RM.


Another possible approach is to you use evidences:

def f[T](t:T)(implicit ev: T<:<Float) {

// float version 

}

def f[T](t:T)(implicit ev: T<:<Int) {

// int version 

}

However I would recommend type classes as a much more elegant solution

like image 36
Edmondo1984 Avatar answered Oct 26 '22 09:10

Edmondo1984


You might want to look into macros: http://scalamacros.org/. Macros are custom functions that are run during compilation and can dynamically generate code based on compile-time computations.

like image 44
Eugene Burmako Avatar answered Oct 26 '22 08:10

Eugene Burmako