Reputation: 488
This is potentially super easy, but I can't find any documentation on my problem.
There are two ways to define a functions in Scala, one with the def
and the other with the val
keyword. As an adept in functional programming, I'd like to use the latter more.
Now I have a problem: It's no problem to write a def
function with a polymorphic type parameter:
def function[T](n: T) = {print(n)} // syntactically fine
How to do the same thing with the val
keyword still eludes me though. This naive approach is syntactically invalid:
val function[T]: (a: T) => print(a) // Doesn't compile
That said, it is absolutely possible that I misunderstand Scala's approach on polymorphism and generics here.
Upvotes: 1
Views: 167
Reputation: 27535
In Scala 2 it is impossible to define parametric function, only method.
In Scala 3 polymorphic function type is introduced:
val fun: [A] => A => Unit = [A] => a => println(a.toString)
Workaround used in 2 by Cats and friends were traits with polymorphic apply
trait MySpecialFunctionlikeThing {
def apply[A](a: A): Unit
}
Unfortunately, single abstract method (SAM) doesn't work with things like that, so some tricks were used to make it easy to lift function into such methods:
object MySpecialFunctionlikeThing {
type Arbitrary
def lift(f: Arbitrary => Unit): MySpecialFunctionlikeThing =
new MySpecialFunctionlikeThing {
def apply[A](a: A): Unit = f(a.asInstanceOf[Arbitrary])
}
}
val fun = MySpecialFunctionlikeThing.lift(a => println(a))
The latter I saw in several different forms: the above, one using existential types and one using one of the above for method signature and macro for implementation (see FunctionK.lift
).
Quite often, though, you can get away with what you used that is parametric, nullary method returning non-parametric function.
def fun[A]: A => Unit = a => println(a)
Upvotes: 6
Reputation: 4577
This would require higher-rank types, which isn't supported in Scala 2.
It is supported in Scala 3: https://dotty.epfl.ch/docs/reference/new-types/polymorphic-function-types.html
Upvotes: 1