Skip to content

Instantly share code, notes, and snippets.

@Sintrastes
Created November 2, 2021 14:16
Show Gist options
  • Save Sintrastes/b8a6b0317fe82661d59ba22131a08f25 to your computer and use it in GitHub Desktop.
Save Sintrastes/b8a6b0317fe82661d59ba22131a08f25 to your computer and use it in GitHub Desktop.
Example of compile-time resolution of serializers/deserializers in a language with subtype polymorphism (Scala 3).
// Example serializable trait to mimic
// Kotlin @Serializable behavior from
// kotlinx serialization.
trait Serializable[A]:
def serialize(x: A): String
def deserialize(raw: String): Option[A]
class MyClass(val x: Int)
trait SomeInterface:
def x: Int
class MyClassWithInterface(override val x: Int)
extends SomeInterface
// Instance (could be automatically derived via annotation in Kotlin)
// for class. Resolved at compile-time at call-sites.
given Serializable[MyClass] with
def serialize(x: MyClass) =
x.x.toString()
def deserialize(raw: String) =
try
Some(MyClass(raw.toInt))
catch
case e: Exception => None
// Instance (could be automatically derived via annotation in Kotlin)
// for class that is resolved at compile-time at call-sites for the same class,
// but extending an interface.
given Serializable[MyClassWithInterface] with
def serialize(x: MyClassWithInterface) =
x.x.toString()
def deserialize(raw: String) =
try
Some(MyClassWithInterface(raw.toInt))
catch
case e: Exception => None
// Example usage:
// Standalone function with implicit compile-time resolution of serializer based on type
def deserialize[T](using serializer: Serializable[T])(x: String) =
serializer.deserialize(x)
// Compiles
println(deserialize[MyClass]("42"))
// Compiles
println(deserialize[MyClassWithInterface]("42"))
// Compiler error:
// no implicit argument of type Playground.Serializable[Playground.SomeInterface]
// was found for parameter serializer of method deserialize in object Playground
println(deserialize[SomeInterface]("42"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment