Last active
October 29, 2020 21:47
-
-
Save SystemFw/1038a0ba297760efca946bbe5c1650bd to your computer and use it in GitHub Desktop.
Revisions
-
SystemFw revised this gist
Oct 29, 2020 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -10,13 +10,13 @@ import shapeless._ trait Check[T] { type Id def register(t: T): Id def check(registered: Set[Id]): Boolean } object Check { def apply[T](implicit ev: Checks[T]): Check[T] = new Check[T] { type Id = Int def register(t: T): Id = ev.checks.indexWhere(_.apply(t)) def check(registered: Set[Id]): Boolean = ev.checks.indices.forall(registered.contains) } -
SystemFw revised this gist
Oct 28, 2020 . No changes.There are no files selected for viewing
-
SystemFw revised this gist
Oct 28, 2020 . 1 changed file with 44 additions and 63 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,70 +1,48 @@ // stemming from // https://gitter.im/typelevel/general?at=5f987f8161007f7d1b9b4b92 // The idea is // read the JSON files in a directory // try to decode each of them as Event which could be either One or Two, we don't know this at compile time // serialize the values we got, again could be either One or Two and compare it with the content of the JSON file // verify that there was at least a JSON file for One and Two (exhaustivity check) import shapeless._ trait Check[T] { type Id def register[A <: T](t: T): Id def check(registered: Set[Id]): Boolean } object Check { def apply[T](implicit ev: Checks[T]): Check[T] = new Check[T] { type Id = Int def register[A <: T](t: T): Id = ev.checks.indexWhere(_.apply(t)) def check(registered: Set[Id]): Boolean = ev.checks.indices.forall(registered.contains) } trait Checks[T] { def checks: Vector[Any => Boolean] } implicit def base: Checks[CNil] = new Checks[CNil] { def checks = Vector.empty } implicit def inductive[H, T <: Coproduct]( implicit next: Checks[T], castH: Typeable[H] ): Checks[H :+: T] = new Checks[H :+: T] { def checks = (castH.cast(_: Any).isDefined) +: next.checks } implicit def generic[T, R <: Coproduct]( implicit ev: Generic.Aux[T, R], check: Checks[R] ): Checks[T] = new Checks[T] { def checks = check.checks } } @@ -78,25 +56,28 @@ object Ex { } object Exhaustive { val check = Check[Ex.A] val checks: collection.mutable.Set[check.Id] = collection.mutable.Set() checks.add(check.register(Ex.b)) checks.add(check.register(Ex.c)) val result = check.check(checks.toSet) } object NonExhaustive { val check = Check[Ex.A] val checks: collection.mutable.Set[check.Id] = collection.mutable.Set() checks.add(check.register(Ex.b)) val result = check.check(checks.toSet) } // scala> Exhaustive.result // res0: Boolean = true // scala> NonExhaustive.result // res1: Boolean = false -
SystemFw created this gist
Oct 27, 2020 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,102 @@ // Stemming from // https://gitter.im/typelevel/general?at=5f987f8161007f7d1b9b4b92 // The idea is // read the JSON files in a directory // try to decode each of them as Event which could be either One or Two, we don't know this at compile time // serialize the values we got, again could be either One or Two and compare it with the content of the JSON file // verify that there was at least a JSON file for One and Two (exhaustivity check) object Lib { import shapeless._ import shapeless.ops.coproduct._ import cats.syntax.all._ def check[A] = new CheckBuilder[A] class CheckBuilder[A] { def apply[R <: Coproduct]( names: Set[String] )(implicit ev: Generic.Aux[A, R], c: Check[R]) = c(names) } def getName[A, R <: Coproduct]( a: A )(implicit ev: Generic.Aux[A, R], n: GetName[R]): Option[String] = n(a) trait GetName[C <: Coproduct] extends Serializable { def apply(x: Any): Option[String] } object GetName extends GetNameLow { implicit def base[H](implicit castH: Typeable[H]): GetName[H :+: CNil] = new GetName[H :+: CNil] { def apply(x: Any): Option[String] = castH.cast(x).as(castH.describe) } } trait GetNameLow { implicit def inductive[H, T <: Coproduct]( implicit next: GetName[T], castH: Typeable[H] ): GetName[H :+: T] = new GetName[H :+: T] { def apply(x: Any): Option[String] = castH .cast(x) .as(castH.describe) .orElse(next(x)) } } trait Check[T] { def apply(s: Set[String]): Boolean } object Check extends CheckLow { implicit def base: Check[CNil] = new Check[CNil] { def apply(names: Set[String]): Boolean = true } } trait CheckLow { implicit def inductive[H, T <: Coproduct]( implicit next: Check[T], castH: Typeable[H] ): Check[H :+: T] = new Check[H :+: T] { def apply(names: Set[String]): Boolean = names.contains(castH.describe) && next(names) } } } object Ex { sealed trait A case class B() extends A case class C() extends A def b: A = B() def c: A = C() } object Exhaustive { val checks: collection.mutable.Set[String] = collection.mutable.Set() Lib.getName(Ex.b).foreach(checks.add) Lib.getName(Ex.c).foreach(checks.add) val result = Lib.check[Ex.A](checks.toSet) } object NonExhaustive { val checks: collection.mutable.Set[String] = collection.mutable.Set() Lib.getName(Ex.b).foreach(checks.add) val result = Lib.check[Ex.A](checks.toSet) } // scala> Exhaustive.result // res0: Boolean = true // scala> NonExhaustive.result // res1: Boolean = false