1

Is it possible to do match-case over functions? I want to define a behavior for different types of functions. Say I have the following possibilities:

  • f: T => Int
  • f: T => String
  • f: T => Lis[Int]
  • f: T => Boolean
  • f: T => Double
  • ...

and for each of these options I have a function; for example for Int output: def doThisForInt(f: T => Int) = { ... } and this for Boolean output: ` def doThisForBoolean(f: T => Boolean) = { ... }

So now suppose a function definition is given: val f = (input: T) => true. We should choose the corresponding case to f: T => Boolean.

Note that all these functions differ in the output type. Alternatively, given f can I get the output type of this function?

Mifeet
  • 12,949
  • 5
  • 60
  • 108
Daniel
  • 5,839
  • 9
  • 46
  • 85
  • 5
    What is your use-case? It sounds like type classes would be better suited for this, as a giant match/case is a code smell. – Michael Zajac May 13 '16 at 15:24
  • So like define a type for each of these cases? Like one for `f: T => Int`, one for `f: T => Double`, etc? – Daniel May 13 '16 at 15:43
  • 1
    What is the signature for the method that you want to use the match? It wouldn't accept `T => Int` because you want it to be generic, right? Something like: `def doSomething[T, R](f: T => R): ??? = ???` ? What should be returned? – Michael Zajac May 13 '16 at 18:12

1 Answers1

4

TypeTags are what you are looking for:

import scala.reflect.runtime.universe._

def doThisForInt(f: T => Int) = ???

def printType[R: TypeTag](f: T => R) = typeOf[R] match {
  case t if t =:= typeOf[Int] =>
    val toInt: (T) => Int = f.asInstanceOf[T => Int]
    doThisForInt(toInt)
  case t if t =:= typeOf[Double] =>
    // ...
  case t if t =:= typeOf[List[Int]] =>
  // ...
}

printType((x: T) => 1) // int
printType((x: T) => 2.0) // double
printType((x: T) => List(2)) // list

As you can see, it is possible, but not very elegant and against good practices.

Chains of instanceOf checks can often be replaced with virtual methods (see the example) and the result type of function can possibly be a type parameter. It's hard to give more advice without knowing more context for your use case.

Community
  • 1
  • 1
Mifeet
  • 12,949
  • 5
  • 60
  • 108