Created
May 9, 2022 20:41
-
-
Save bishabosha/45cf41dcf843bad145b0884eb5fb52cc to your computer and use it in GitHub Desktop.
Showing how the type class derivation mechanism can be used to add methods to the companion object with low boilerplate from the client side
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Plugin: | |
type Companion | |
val exports: Companion | |
object Plugin: | |
transparent inline def exports[P <: Plugin](using plugin: P): plugin.exports.type = plugin.exports | |
trait Hashable[-T] extends Plugin: | |
extension (t: T) protected def computeHash: Long | |
trait Companion: | |
def hash(t: T): Long = t.computeHash | |
object exports extends Companion | |
object Hashable: | |
def derived[T]: Hashable[T] = new Hashable[T]: | |
extension (t: T) protected def computeHash: Long = System.identityHashCode(t).toLong | |
trait Flags[T <: reflect.Enum] extends Plugin: | |
outer => | |
opaque type FlagSet = Long | |
trait Companion: | |
type FlagSet = outer.FlagSet | |
def EmptyFlagSet: outer.FlagSet = 0L | |
object exports extends Companion | |
object FlagSet: | |
extension (flags: FlagSet) | |
def isEmpty = flags == 0L | |
def | (flag: T): FlagSet = flags | flag.asFlags | |
extension (flag: T) | |
def asFlags: FlagSet = 1L << flag.ordinal | |
object Flags: | |
def derived[T <: reflect.Enum]: Flags[T] = new Flags[T] {} | |
enum Foo derives Hashable, Flags: | |
case A, B, C | |
object Foo: | |
private transparent inline def hash = Plugin.exports[Hashable[Foo]] | |
private transparent inline def flags = Plugin.exports[Flags[Foo]] | |
export hash.*, flags.* | |
@main def Test = | |
println(Foo.hash(Foo.A)) | |
println(Foo.A.asFlags) | |
println(Foo.B.asFlags) | |
println(Foo.C.asFlags) | |
println(Foo.EmptyFlagSet) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment