Skip to content

Instantly share code, notes, and snippets.

@regiskuckaertz
Last active February 7, 2018 12:18
Show Gist options
  • Save regiskuckaertz/c42c7a1d8eeb9136a962faefe5c7cc13 to your computer and use it in GitHub Desktop.
Save regiskuckaertz/c42c7a1d8eeb9136a962faefe5c7cc13 to your computer and use it in GitHub Desktop.
package humbug
package codecs
sealed abstract class Type[T]
case object TyBool extends Type[Boolean]
case object TyByte extends Type[Byte]
case object TyDouble extends Type[Double]
case object TyI16 extends Type[Short]
case object TyI32 extends Type[Int]
case object TyI64 extends Type[Long]
case object TyString extends Type[String]
case object TyStruct extends Type[TStruct]
case class TyList[A](a: Type[A]) extends Type[List[A]]
case class TySet[A](a: Type[A]) extends Type[Set[A]]
case class TyMap[K, V](k: Type[K], v: Type[V]) extends Type[Map[K, V]]
case object TyDyn extends Type[Dynamic]
sealed trait Dynamic
case class Dyn[A](ta: Type[A], a: A) extends Dynamic
object Dynamic {
def identity[A](a: A): A = a
def tequal[A, B](ta: Type[A], tb: Type[B]): Option[A ⇒ B] = (ta, tb) match {
case (TyBool, TyBool) ⇒ Some(identity(_))
case (TyByte, TyByte) ⇒ Some(identity(_))
case (TyDouble, TyDouble) ⇒ Some(identity(_))
case (TyI16, TyI16) ⇒ Some(identity(_))
case (TyI32, TyI32) ⇒ Some(identity(_))
case (TyI64, TyI64) ⇒ Some(identity(_))
case (TyString, TyString) ⇒ Some(identity[String](_))
case (TyStruct, TyStruct) ⇒ Some(identity[TStruct](_))
case (TyList(tta), TyList(ttb)) ⇒ tequal(tta, ttb).map { cst ⇒ la ⇒ la.map(cst) }
case (TySet(tta), TySet(ttb)) ⇒ tequal(tta, ttb).map { cst ⇒ sa: Set[_] ⇒ sa.map(cst) }
case (TyMap(ttka, ttva), TyMap(ttkb, ttvb)) ⇒ for {
castk ← tequal(ttka, ttkb)
castv ← tequal(ttva, ttvb)
} yield { mkv: Map[_, _] ⇒ mkv.map { case (k, v) ⇒ castk(k) -> castv(v) } }
case _ ⇒ None
}
def cast[A](dyn: Dynamic, ta: Type[A]): Option[A] = dyn match {
case Dyn(tta, a) ⇒ tequal(tta, ta).map { f ⇒ f(a) }
}
}
@regiskuckaertz
Copy link
Author

At line 34, the compiler complains that map is ambiguous because the inferred type of cst is too broad.

But if I use type variables:

    case (TSet(tta: Type[x]), TSet(ttb: Type[y]))  tequal(tta, ttb).map { (cst: x  y)  (sa: Set[x])  sa.map(cst) }

then the compiler issues a warning that the code inside map is unreachable. 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment