Created
February 28, 2018 13:05
-
-
Save yasuabe/21fa9e487eb43b27eb34b8f4e1538352 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
package type_classes.partialorder | |
import cats.PartialOrder | |
import cats.syntax.partialOrder._ | |
import cats.instances.AllInstances | |
import cats.kernel.BoundedSemilattice | |
import cats.kernel.laws.discipline.{BoundedSemilatticeTests, PartialOrderTests} | |
import org.scalacheck.{Arbitrary, Gen} | |
import org.specs2.Specification | |
import org.typelevel.discipline.specs2.Discipline | |
import scala.reflect.runtime.universe._ | |
class TypeBoundedSemilatticeSpec extends Specification with Discipline with AllInstances { | |
implicit val typePartialOrder: PartialOrder[Type] = (x: Type, y: Type) => | |
(x <:< y, y <:< x) match { | |
case (true, true) => 0.0 | |
case (true, _) => -1.0 | |
case (_ , true) => 1.0 | |
case _ => Double.NaN | |
} | |
implicit val typeBoundedSemilattice: BoundedSemilattice[Type] = new BoundedSemilattice[Type] { | |
val empty: Type = typeOf[Nothing] | |
def superTypesOf(t: Type): Set[Type] = t.baseClasses.map(t.baseType).toSet + t | |
def combine(x: Type, y: Type): Type = | |
if (x == empty) y | |
else if (y == empty) x else | |
(superTypesOf(x) intersect superTypesOf(y)) | |
.toList | |
.sortWith((x, y) => x <= y) match { | |
case h :: Nil => h | |
case h1 :: h2 :: _ => | |
assert((h1 tryCompare h2).nonEmpty, "no sumpremum!") | |
h1 | |
} | |
} | |
trait A; trait B; trait C | |
trait D extends B; trait E extends B with C | |
implicit def arbType: Arbitrary[Type] = Arbitrary( | |
Gen.oneOf(typeOf[Any], typeOf[A], typeOf[B], typeOf[C], typeOf[D], typeOf[E], typeOf[Nothing])) | |
private val checkTypePartialOrder = { | |
implicit val arbF: Arbitrary[Type => Type] = Arbitrary(Gen.const(t => t)) | |
checkAll("partial ordered set of types", PartialOrderTests[Type].partialOrder) | |
} | |
private val checkTypeBoundedSemilattice = | |
checkAll("bounded semilattice of types", BoundedSemilatticeTests[Type].boundedSemilattice) | |
def is = s2""" | |
set of types satisfies partial order laws $checkTypePartialOrder | |
set of types satisfies bounded semilattice laws $checkTypeBoundedSemilattice | |
""" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment