The problem I'm having is that I'm getting infinite recursion when I try to define a type class on a union.
trait Foo[A]:
extension (a: A)
def bar: String
Now suppose I have the following givens defined:
given Foo[Int] with ...
given Foo[String] with ...
Now I want to create a union
type Value = String | Int
and, of course, Value
should be a member of the type class. But if I do this:
given Foo[Value] with
extension (v: Value)
def bar: String = v match
case i: Int => i.bar
case s: String => s.bar
the problem is that i.bar
and s.bar
call the bar
that goes with Value
, not with Int
or String
, and I end up with infinite recursion. And casting them doesn't help.
Because bar
is an extension function, I'm not sure how to get Foo[Int]
and Foo[String]
so that I could make the calls directly. Is there a way out of this, or have I coded myself into a corner?
How about this:
scala> given Foo[Value] with
| extension (v: Value)
| def bar: String = v match
| case i: Int => summon[Foo[Int]].bar(i)
| case s: String => summon[Foo[String]].bar(s)
|
// defined object given_Foo_Value