Created
March 26, 2022 16:04
-
-
Save deanwampler/e703f886239b3f5602131b281fff0d42 to your computer and use it in GitHub Desktop.
This file contains 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 progscala3.erased | |
import scala.annotation.implicitNotFound | |
import scala.language.experimental.erasedDefinitions | |
sealed trait Emptiness | |
final class Empty extends Emptiness | |
final class NotEmpty extends Emptiness | |
@implicitNotFound("The seq must be empty") | |
class IsEmpty[-E <: Emptiness] | |
object IsEmpty: | |
erased given IsEmpty[Empty] = new IsEmpty[Empty] | |
@implicitNotFound("The seq must be not empty") | |
class IsNotEmpty[-E <: Emptiness] | |
object IsNotEmpty: | |
erased given IsNotEmpty[NotEmpty] = new IsNotEmpty[NotEmpty] | |
sealed trait ESeq[+H, T <: ESeq[H,?]]: | |
type E <: Emptiness | |
def hd: H | |
def tl: T | |
def head(using erased ne: IsNotEmpty[E]): H = hd | |
def tail(using erased ne: IsNotEmpty[E]): T = tl | |
def +:[H2 >: H](h2: H2): NotEmptySeq[H2, this.type] | |
case class NotEmptySeq[+H, T <: ESeq[H,?]] private (hd: H, tl: T) extends ESeq[H, T]: | |
type E = NotEmpty | |
def +:[H2 >: H](h2: H2): NotEmptySeq[H2, this.type] = | |
NotEmptySeq(h2, this) | |
override def toString: String = s"$head +: ${tail.toString}" | |
object NotEmptySeq: | |
def apply[H, T <: ESeq[H,?]](hd: H, tl: NotEmptySeq[H, T]): NotEmptySeq[H, NotEmptySeq[H, T]] = | |
new NotEmptySeq(hd, tl) | |
def apply[H](hd: H): NotEmptySeq[H, EmptySeq.type] = new NotEmptySeq(hd, EmptySeq) | |
case object EmptySeq extends ESeq[Nothing, Nothing]: | |
type E = Empty | |
def hd: Nothing = ??? | |
def tl: Nothing = ??? | |
def +:[H](h: H): NotEmptySeq[H, this.type] = NotEmptySeq(h) | |
override def toString: String = "EmptySeq" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment