Skip to content

Instantly share code, notes, and snippets.

@velvia
Created September 30, 2015 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save velvia/4e923bf6eac6b4e8e7a0 to your computer and use it in GitHub Desktop.
Save velvia/4e923bf6eac6b4e8e7a0 to your computer and use it in GitHub Desktop.
Calling a function by type parameter in Scala

Let's say you have a Scala function which takes type parameter:

  def myFunc[K]: T

Let's say I have several functions like that. Right now, if K could be one of several different values, I'd need some code like the following:

  kType match {
    case KIsInt =>  myFunc[Int]
    case KIsLong => myFunc[Long]
  }

I'd like a generic wrapper function that can switch on kType and call different functions. Is this possible? Something like this.

  def kFuncCall[T](kType: KType)(callFunc: [K] => T): T = {
    kType match {
      case KIsLong    => callFunc[Long]
      case KIsInt     => callFunc[Int]
    }
@gclaramunt
Copy link

I'm pretty sure you're trying to do something else (or I misunderstood really bad), but if you just want to pass a different type based on KType, you can put an abstract type member in KType:

trait KType { type K }
case class KIsInt() extends KType { type K=Int }

def callFunc[K]:List[K] = Nil 
def build(kType:KType) = callFunc[kType.K]

scala> build(KIsInt())
res1: List[Int] = List()

If you can't modify KType you do it indirectly via implicits.

Now, the real problem seems the definition of callFunc ... :)

@velvia
Copy link
Author

velvia commented Oct 1, 2015

@gclaramunt: hm, I'll try that. That could definitely work, I think

@velvia
Copy link
Author

velvia commented Oct 9, 2015

@gclaramunt: so the above code works for different KType's, but if I need something to work with type classes and implicits then it doesn't work. IE, what if callFunc is actually def callFunc[K: SomeTypeClass]: List[K]
The problem is then that Scala won't be able to find the implicit based on kType.K

@gclaramunt
Copy link

Interesting... I'm doing horrible things with typeclasses and types in https://github.com/gclaramunt/scala-reggen but at the end I resort to casting :(

The first thing it comes to mind is if you know you'll need a typeclass instance you can (again) add it to KType and use it explicitly: callFunc[kType.K](kType.typeClassOfK)

trait KType { 
  type K
  type TypeClassOfK <: SomeTypeClass
 }

case class KIsInt() extends KType { 
  type K=Int 
  type TypeClassOfK = TypeClassForInt
}

is not the most elegant way but I think it will work
(maybe is time to mine Scalaz for more sophisticated techniques, :) )

@velvia
Copy link
Author

velvia commented Oct 14, 2015

@gclaramunt thanks. I tried looking in Shapeless but didn't find anything that would help. Maybe Scalaz. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment