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

japgolly.microlibs.nonempty.NonEmpty.scala Maven / Gradle / Ivy

package japgolly.microlibs.nonempty

import japgolly.univeq.UnivEq
import scalaz.Equal

/**
 * Type indicating that its value has been proven to be non-empty.
 */
final class NonEmpty[A] private[NonEmpty] (val value: A) extends AnyVal {
  override def toString = s"NonEmpty($value)"
}

object NonEmpty {

  @inline implicit def autoNonEmptyValue[A](n: NonEmpty[A]): A =
    n.value

  /*
   * scala> class X(val i: Int) extends AnyVal
   * defined class X
   *
   * scala> new X(3) == new X(3)
   * res0: Boolean = true
   */
  @inline implicit def nonEmptyUnivEq[A: UnivEq]: UnivEq[NonEmpty[A]] =
    UnivEq.force

  @inline def nonEmptyEqual[A](implicit e: Equal[A]): Equal[NonEmpty[A]] =
    e.contramap(_.value)

  @inline def force[A](a: A): NonEmpty[A] =
    new NonEmpty(a)

  @inline def apply[I, O](i: I)(implicit proof: Proof[I, O]): Option[O] =
    proof.tryProve(i)

  @inline def require_![I, O](i: I)(implicit proof: Proof[I, O]): O =
    NonEmpty(i) getOrElse sys.error(s"Data is empty: $i")

//  def disj[I, O](i: I)(implicit proof: Proof[I, O]): I \/ O =
//    NonEmpty(i).fold[I \/ O](-\/(i))(\/-.apply)

  // -------------------------------------------------------------------------------------------------------------------
  //  Proofs

  final case class Proof[I, O](tryProve: I => Option[O]) extends AnyVal

  type ProofMono[A] = Proof[A, NonEmpty[A]]

  trait ProofImplicitsLo {
    def testEmptiness[A](isEmpty: A => Boolean): ProofMono[A] =
      Proof(a => if (isEmpty(a)) None else Some(new NonEmpty(a)))

    implicit def proveTraversable[A <: Traversable[_]]: ProofMono[A] =
      testEmptiness(_.isEmpty)
  }

  object Proof extends ProofImplicitsLo {
    implicit def proveNES[A: UnivEq]: Proof[Set[A], NonEmptySet[A]] =
      Proof(NonEmptySet.option[A])

    implicit def proveNEV[A]: Proof[Vector[A], NonEmptyVector[A]] =
      Proof(NonEmptyVector.option[A])
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy