Skip to content

Instantly share code, notes, and snippets.

@neko-kai
Created March 13, 2018 02:23
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 neko-kai/d6a7127b7b0d39a963d3102c7128a1de to your computer and use it in GitHub Desktop.
Save neko-kai/d6a7127b7b0d39a963d3102c7128a1de to your computer and use it in GitHub Desktop.
FlatMap Covariant override in scala
class AbsBuilder[+A] {
type This[+X] <: AbsBuilder[X]
def add: AbsBuilder[A] = this
def flatMap[B](f: A => This[B]): AbsBuilder[B] =
new AbsBuilder[B]
def map[B](f: A => B): AbsBuilder[B] =
new AbsBuilder[B]
}
class CBuilder[+A] extends AbsBuilder[A] {
override type This[+B] = CBuilder[B]
override def add: CBuilder[A] = this
override def flatMap[B](f: A => This[B]): CBuilder[B] =
new CBuilder[B]
override def map[B](f: A => B): CBuilder[B] =
new CBuilder[B]
def cspecific: CBuilder[A] = this
}
new CBuilder[Unit]
.cspecific
.add
.add
.add
.map(identity)
.cspecific
.flatMap(_ => new CBuilder[Int])
.cantUpcast
.cspecific
.cantUpcast
.cspecific
implicit class AOps[A](a: AbsBuilder[A]) {
def cantUpcast: AbsBuilder[A] = a
}
implicit class COps[A](c: CBuilder[A]) {
def cantUpcast: CBuilder[A] = c
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment