Created
March 20, 2025 15:15
-
-
Save scarf005/739c0e632df606ce904e4da8fcc95cea to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// https://xebia.com/blog/how-to-derive-type-class-instances-with-shapeless-3/ | |
//> using dep org.typelevel::shapeless3-deriving::3.5.0 | |
package deriving | |
import shapeless3.deriving.* | |
trait Show[A]: | |
def show(a: A): String | |
object Show: | |
given Show[Int] = _.toString | |
given Show[Boolean] = _.toString | |
given Show[String] = identity(_) | |
def deriveShowProduct[ | |
A: {Labelling as labelling, ([x] =>> K0.ProductInstances[Show, x]) as pInst}, | |
]: Show[A] = | |
(a: A) => | |
labelling.elemLabels.zipWithIndex | |
.map { (label, index) => | |
val value = pInst.project(a)(index)([t] => (st: Show[t], pt: t) => st.show(pt)) | |
s"$label = $value" | |
} | |
.mkString(s"${labelling.label}(", ", ", ")") | |
def deriveShowSum[A: ([x] =>> K0.CoproductInstances[Show, x]) as cInst]: Show[A] = | |
(a: A) => cInst.fold(a)([a] => (st: Show[a], a: a) => st.show(a)) | |
inline given derived[A: K0.Generic as gen]: Show[A] = | |
gen.derive(deriveShowProduct, deriveShowSum) | |
extension [A: Show as s](a: A) inline def show: String = s.show(a) | |
case class Pos(x: Int, y: Int) derives Show | |
enum Expr derives Show: | |
case Var(name: String) | |
case Add(left: Expr, right: Expr) | |
case Mul(left: Expr, right: Expr) | |
@main def main() = | |
println(Pos(3, 4).show) | |
println(Expr.Add(Expr.Var("x"), Expr.Mul(Expr.Var("y"), Expr.Var("z"))).show) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment