fthomas / refined

Refinement types for Scala
MIT License
1.71k stars 154 forks source link

Compile-time refinement for cons #575

Open steinybot opened 6 years ago

steinybot commented 6 years ago

It would be cool if this worked:

type NonEmptySeq[A] = immutable.Seq[A] Refined NonEmpty

object NonEmptySeq {
  def apply[A]: RefinedTypeOps[NonEmptySeq[A], immutable.Seq[A]] = {
    new RefinedTypeOps[NonEmptySeq[A], immutable.Seq[A]]
  }
}

val a = "refined"
val b = "types" :: "are" :: "cool!"
NonEmptySeq[String](a :: b)
// or at least
NonEmptySeq[String](::(a, b))
fthomas commented 5 years ago

This seems to work:

object collection {
  type NonEmptyList[A] = List[A] Refined NonEmpty

  object NonEmptyList {
    class NonEmptyListOps[A] extends RefinedTypeOps[NonEmptyList[A], List[A]] {
      def fromCons(cons: ::[A]): NonEmptyList[A] =
        Refined.unsafeApply(cons)
    }

    def apply[A]: NonEmptyListOps[A] = new NonEmptyListOps[A]
  }
}
scala> NonEmptyList[String].fromCons(::("hello", Nil))
res5: NonEmptyList[String] = List(hello)

I'm open to adding this to the types package.