Skip to content

Allow export of extension clause parameters #17678

Closed
@adampauls

Description

@adampauls

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions