Scala does not support polymorphic functions, unlike methods. This is due to the first-class character value of functions that are just instances of FunctioN traits. These functions are classes, and they need types to be bound on the ad site.
If we take the flip method and try to extend it to a function, we will see:
val flipFn = flip _
We will return a value like:
((Nothing, Nothing) => Nothing) => (Nothing, Nothing) => Nothing
Due to the fact that none of the types was connected, therefore, the compiler refers to the buttom Nothing type.
However, not all hope is lost. There is a library called shapeless that allows us to define polymorphic functions through PolyN .
We can implement flip as follows:
import shapeless.Poly1 object flip extends Poly1 { implicit def genericCase[A, B, C] = at[(A, B) => C](f => (b: B, a: A) => f(a, b)) }
flip is no different from the FunctionN attribute; it defines the apply method that will be called.
We use it as follows:
def main(args: Array[String]): Unit = { val minus = (a: Int, b: Int) => a - b val f = flip(minus) println(f(3, 5)) }
Yielding:
2
This also works for String :
def main(args: Array[String]): Unit = { val stringConcat = (a: String, b: String) => a + b val f = flip(stringConcat) println(f("hello", "world")) }
Yielding:
worldhello