scalaprops.Or.scala Maven / Gradle / Ivy
package scalaprops
import scalaz._
import Or.{L, R}
sealed abstract class Or
sealed abstract class :-:[+H, +T <: Or] extends Or
sealed abstract class OrConsInstances {
implicit def order[H, T <: Or](implicit H: Order[H], T: Order[T]): Order[H :-: T] =
Order.order{
case (L(a), L(b)) =>
H.order(a, b)
case (R(a), R(b)) =>
T.order(a, b)
case (R(_), L(_)) =>
Ordering.LT
case (L(_), R(_)) =>
Ordering.GT
}
}
object :-: extends OrConsInstances {
implicit def equal[H, T <: Or](implicit H: Equal[H], T: Equal[T]): Equal[H :-: T] =
Equal.equal{
case (L(a), L(b)) =>
H.equal(a, b)
case (R(a), R(b)) =>
T.equal(a, b)
case _ =>
false
}
implicit def orGen[A, B <: Or](implicit A: Gen[A], B: Gen[B]): Gen[A :-: B] = {
if(B eq Or.Empty.orEmptyGen){
A.map[A :-: B](Or.L(_))
}else {
Gen.frequency(
1 -> A.map[A :-: B](Or.L(_)),
3 -> B.map[A :-: B](Or.R(_))
)
}
}
}
object Or {
final case class L[+H, +T <: Or](head : H) extends :-:[H, T] {
override def toString = head.toString
}
final case class R[+H, +T <: Or](tail : T) extends :-:[H, T] {
override def toString = tail.toString
}
sealed trait Empty extends Or
object Empty {
implicit val instance: Order[Empty] =
Order.order((_, _) => Ordering.EQ)
implicit val orEmptyGen: Gen[Or.Empty] =
Gen.oneOfLazy(Need(???))
}
final class MkOr[C <: Or] private[Or] {
def apply[T](t: T)(implicit inj: Inj[C, T]): C = inj(t)
private[scalaprops] def _apply[T](implicit inj: Inj[C, T]): T => C = inj(_)
}
def apply[C <: Or]: MkOr[C] = new MkOr[C]
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy