Skip to content

Instantly share code, notes, and snippets.

@jliszka
Created June 7, 2012 21:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jliszka/2891751 to your computer and use it in GitHub Desktop.
Save jliszka/2891751 to your computer and use it in GitHub Desktop.
sealed trait Limited
sealed trait Unlimited
sealed trait Lim extends Limited with Unlimited
sealed trait Skipped
sealed trait Unskipped
sealed trait Sk extends Skipped with Unskipped
sealed trait Selected
sealed trait Unselected
sealed trait Sel extends Selected with Unselected
class AddLimit[-In, +Out]
implicit def addLimit[Rest >: Sel with Sk]: AddLimit[Rest with Unlimited, Rest with Limited] = null
class MaybeAddLimit[-In, +Out1, +Out2] extends AddLimit[In, Out1]
implicit def maybeAddLimit[Rest >: Sel with Sk]: MaybeAddLimit[Rest with Unlimited, Rest with Limited, Rest] = null
class AddSkip[-In, +Out]
implicit def addSkip[Rest >: Lim with Sel]: AddSkip[Rest with Unskipped, Rest with Skipped] = null
class AddSelect[-In, +Out]
implicit def addSelect[Rest >: Lim with Sk]: AddSelect[Rest with Unselected, Rest with Selected] = null
class Query[+T] {
def limit[T2](n: Int)(implicit ev: AddLimit[T, T2]): Query[T2] = this.asInstanceOf[Query[T2]]
def skip[T2](n: Int)(implicit ev: AddSkip[T, T2]): Query[T2] = this.asInstanceOf[Query[T2]]
def select[T2]()(implicit ev: AddSelect[T, T2]): Query[T2] = this.asInstanceOf[Query[T2]]
def fetch()(implicit ev: T <:< Limited): List[String] = Nil
}
val q = new Query[Unlimited with Unskipped with Unselected]
// I tried [State <: S3, S2 <: S3, S3] also.
// It inferred S3 to be Unlimited with Unskipped with Unselected and then couldn't find the implicit.
def maybeLimitQuery[State, S2, S3](b: Boolean, q: Query[State])
(implicit ev: MaybeAddLimit[State, S2, S3]): Query[S3] = {
val qq = if (b)
q.limit(3) // Query[S2]
else
q // Query[State]
// State <: S3 and S2 <: S3, but the compiler doesn't know that
qq.asInstanceOf[Query[S3]]
}
maybeLimitQuery(true, q)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment