Skip to content

Instantly share code, notes, and snippets.

@zcox
Created October 18, 2011 16:36
Show Gist options
  • Save zcox/1295890 to your computer and use it in GitHub Desktop.
Save zcox/1295890 to your computer and use it in GitHub Desktop.
Typesafe fluent interface hierarchy using type constructors
trait PipeFunction[A, B]
class NullPipeFunction[A, B] extends PipeFunction[A, B]
trait Pipe[S, E]
class Pipeline[S, E, T[S, E]] extends Pipe[S, E] {
def add[F](pipe: Pipe[E, F]): T[S, F] =
throw new UnsupportedOperationException()
}
class FluentPipeline[S, E, T[S, E]] extends Pipeline[S, E, T] {
def filter1[F](f: PipeFunction[E, F]): T[S, F] =
throw new UnsupportedOperationException()
def filter2[F](f: PipeFunction[E, F]): T[S, F] =
throw new UnsupportedOperationException()
}
class GremlinPipeline[S, E] extends FluentPipeline[S, E, GremlinPipeline]
object Test {
def main(args: Array[String]) {
val long2Float = new NullPipeFunction[Long, Float]
val float2Double = new NullPipeFunction[Float, Double]
val int2Long = new GremlinPipeline[Int, Long]
val int2Float = int2Long.filter1(long2Float) //GremlinPipeline[Int, Float] properly inferred
val int2Double = int2Float.filter2(float2Double) //GremlinPipelin[Int, Double] properly inferred
//GremlinPipeline[Int, Double] properly inferred
val int2Double2 = new GremlinPipeline[Int, Long].filter1(long2Float).filter2(float2Double)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment