Although it is possible to define a ADT where some term has a given parameter, it does not seem possible to use it:
trait Bar[A]:
def hello(value: A): Int
extension (value: A) def h: Int = hello(value)
object Bar:
given Bar[String] with
def hello(value: String) = value.length
enum Foo:
case Case[A: Bar](value: A)
object Foo:
val test: Foo = Case("world")
test match
case Case(value) => value.h // Compile error: value h is not a member of A$1
I tried pattern matching on the given
case Case(value)(B @ given Bar[?])
But there is a syntax error: '=>' expected, but '(' found
Depending on the use case, you could use a named context parameter instead of the context bound:
trait Bar[A]:
def hello(value: A): Int
extension (value: A) def h: Int = hello(value)
object Bar:
given Bar[String] with
def hello(value: String) = value.length
enum Foo:
case Case[A: Bar](value: A)(using private[Foo] val ev: Bar[A])
object Foo:
val test: Foo = Case("world")
test match
case c @ Case(value) => c.ev.h(value)
I’m not sure if this already too explicit. And it’s more verbose, admittedly.