Closed
Description
After this PR, it is possible to export members in extension clauses like so:
extension (t: T)(using inst: Foo[T])
private def tCeremony = t
export tCeremony.*
private def instCeremony = inst
export instCeremony.*
It would be nice to be able to do
extension (t: T)(using inst: Foo[T])
export t.*
export inst.*
This might seem a little silly, but it would be very useful for typeclass programing. With inheritance, it is nice to be able to declare an interface using a val
or def
on a trait
and then "implement" it with a param on a case class
. With typeclasses, you can already do a similar thing:
trait Typeclass[Self]:
extension(self: Self)
def prop1: String
def prop2: Int
def method(x: Int): String
case class Foo(prop1: String, prop2: Int, extraProp: Boolean):
def method(x: Int): String = x.toString
given Typeclass[Foo] with
extension (self: Foo)
private def selfCeremony = self
export selfCeremony.*
def takesTypeclass[T: Typeclass](t: T): String = t.prop1 + t.method(t.prop2)
object Test {
takesTypeclass(Foo("a", 2, true))
}
but that extra ceremony in the extension is a little ugly. Similarly, as suggested by this thread, it would be nice to be able to call "static" methods on a typeclass (those not naturally written as extension (self: Self) def ...
using static syntax:
trait Typeclass[Self]:
def static(x: Int): Int
object Typeclass:
extension [Self](n: Typeclass.type)(using tc: Typeclass[Self])
private def tcCeremony = tc
export tcCeremony.*
def takesTypeclass[T: Typeclass](t: T): Int = Typeclass.static(5)
// instead of def takesTypeclass[T: Typeclass](t: T): Int = summon[Typeclass[T]].static(5)
// or def takesTypeclass[T](t: T)(using tc: Typeclass[T]): Int = tc.static(5)
I think this is probably a very simple change, but I could not figure out how to do it myself.
Metadata
Metadata
Assignees
Labels
No labels