Reputation: 61
I'm somewhat new to Scala (specifically, Scala 3) - so I understand that the following question might be dumb/naïve.
I know that a polymorphic method type below works.
def zeroMethod[A:Numeric] = Numeric[A].zero
Here Numeric is the context bound on the generic type A.
Notice that
scala> zeroMethod[Int]
yields val res0: Int = 0
. Or with the help of type inference:
scala> val a = zeroMethod[Int]
val a: Int = 0
A slight extension of this is
def zeroMethodFromVal[A:Numeric](x : A) = Numeric[A].zero
The only real use that the argument x
supplies is that it facilitates type-inference.
Specifically,
scala> zeroMethodFromVal(5)
val res1: Int = 0
From there, I wanted to write a polymorphic function type that mirrored the behavior of the polymorphic method type.
How can you add context bounds to polymorphic function types? Or is it just not possible since the context bounds are simply syntactic sugar for passing implicit arguments?
When I attempt to make a function-equivalent to zeroMethod
, it gives me all sorts of errors ... some that depart from the topic at hand. Thus, I will omit that particular code-snippet. However, it seems like it should be feasible to make a function-equivalent to zeroMethodFromVal
and that doesn't distract from the topic at hand.
Specifically, my (first) attempt was:
val zeroFunFromVal : [A:Numeric] => A => A = [A:Numeric] => (x: A) => zeroMethodFromVal[A](x)
This fails, producing a syntax error. It doesn't like the added context bound to the generic.
Of course, if I try to eliminate the context bounds altogether, then I obviously get a type error, because zeroMethodFromVal
doesn't receive the implicit that it requires (i.e. the context bounds aren't being enforced on the generic).
Is there a way to get this polymorphic function type to work like the polymorphic method type? (that includes the context bounds?)
Upvotes: 1
Views: 209
Reputation: 15090
With Scala 3, the syntax to define implicit parameters in function declaration is ImplicitType ?=> ...
.
In your case, the following works:
val zeroFunFromVal: [A] => A => Numeric[A] ?=> A =
[A] => (x: A) => (evA: Numeric[A]) ?=> zeroMethodFromVal[A](x)(evA)
val five: Int = 5
zeroFunFromVal.apply(five) // Gives 0
Upvotes: 6