Last active
September 5, 2023 11:59
-
-
Save tschuchortdev/4b5d5e867451c7b4b10458cba47dba51 to your computer and use it in GitHub Desktop.
Scala 2 existential typeclass pattern
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
object Main { | |
def main(args: Array[String]) = { | |
implicit val showInt = new Show[Int] { | |
override def show(a: Int): String = a.toString | |
} | |
| |
implicit val readInt = new Read[Int] { | |
override def read(s: String): Int = s.toInt | |
} | |
| |
val a = 5 | |
| |
val e = Exists[Show](a) | |
| |
e match { | |
case Exists(value, tc) => println(tc.show(value)) | |
} | |
} | |
} | |
| |
| |
trait Show[A] { | |
def show(a: A): String | |
} | |
| |
trait Read[A] { | |
def read(s: String): A | |
} | |
| |
sealed trait Exists[C[_]] { | |
type Value | |
val value: Value | |
val typeClassInstance: C[Value] | |
| |
final def use[R](f: C[Value] => Value => R): R = f(typeClassInstance)(value) | |
} | |
| |
object Exists { | |
private class ExistsConcrete[A, C[_]](override val value: A, override val typeClassInstance: C[A]) extends Exists[C] { | |
override type Value = A | |
} | |
| |
| |
def apply[C[_]]: ApplyPartialApplicationHelper1[C] = new ApplyPartialApplicationHelper1() | |
| |
class ApplyPartialApplicationHelper1[C[_]] private[Exists] { | |
def apply[A](a: A)(implicit tc: C[A]): Exists[C] = new ExistsConcrete[A, C](a, tc) | |
} | |
| |
def unapply[C[_]](e: Exists[C]): Some[(e.Value, C[e.Value])] = Some(e.value, e.typeClassInstance) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment