Created
March 5, 2016 21:45
-
-
Save ceedubs/37e351b5d8a80f4c5e68 to your computer and use it in GitHub Desktop.
The start of an HList implementation from my nescala unconf session. There are two errors that are left to the reader as an exercise. Hint: it's mostly right but a couple types are incorrect.
This file contains hidden or 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
import HList._ | |
sealed abstract class HList | |
case object HNil extends HList | |
final case class HCons[H, T <: HList](head: H, tail: T) extends HList | |
object HList { | |
type HNil = HNil.type | |
type ::[H, T <: HList] = HCons[H, T] | |
implicit final class HListOps[L <: HList](l: L) { | |
def filterNot[A](implicit f: FilterNot[A, L]): f.Out = | |
f(l) | |
} | |
} | |
trait FilterNot[A, L <: HList] { | |
type Out <: HList | |
def apply(l: L): Out | |
} | |
object FilterNot extends LowPriorityFilterNotInstances { | |
implicit def filterNotHNil[A]: Aux[A, HNil, HNil] = new FilterNot[A, HNil] { | |
type Out = HNil | |
def apply(l: HNil): HNil = HNil | |
} | |
implicit def filterNotIsType[A, H <: A, T <: HList](implicit f: FilterNot[A, T]): Aux[A, H :: T, f.Out] = new FilterNot[A, H :: f.Out] { | |
type Out = f.Out | |
def apply(l: H :: T): f.Out = f(l.tail) | |
} | |
} | |
trait LowPriorityFilterNotInstances { | |
type Aux[A, L <: HList, O <: HList] = FilterNot[A, L]{ type Out = O } | |
implicit def filterNotIsntType[A, H, T <: HList](implicit f: FilterNot[A, T]): Aux[A, H :: T, H :: f.Out] = new FilterNot[A, H :: f.Out] { | |
type Out = H :: f.Out | |
def apply(l: H :: T): H :: f.Out = HCons(l.head, f(l.tail)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment