How do you define a type class for a union of types?

47 views Asked by At

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?

1

There are 1 answers

1
esse On BEST ANSWER

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