All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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