Created
June 7, 2012 21:48
-
-
Save jliszka/2891751 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
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