Skip to content

Instantly share code, notes, and snippets.

@EECOLOR
Last active August 29, 2015 14:03
Show Gist options
  • Save EECOLOR/5cac1ed4972d1848e1a4 to your computer and use it in GitHub Desktop.
Save EECOLOR/5cac1ed4972d1848e1a4 to your computer and use it in GitHub Desktop.
Collecting types in a type list (an HList without actual values). Adding and Finding types in that list on a a type level
package test2
import scala.language.higherKinds
trait T1[A]
trait T2[A]
trait T3[A]
trait TypeList
trait Nil extends TypeList
trait ::[Head[_], Tail <: TypeList] extends TypeList
object TypeList {
type Apply[Head[_]] = Head :: Nil
trait Add[List <: TypeList, Head[_]] {
type Out <: TypeList
}
trait LowerPriorityAdd {
implicit def addToList[List <: TypeList, F[_]] =
new Add[List, F] {
type Out = F :: List
}
}
object Add extends LowerPriorityAdd {
implicit def alreadyInList[List <: TypeList, F[_]](
implicit f: Find[F, List]) =
new Add[List, F] {
type Out = List
}
}
trait Find[F[_], In]
object Find {
implicit def isInTail[F[_], Head[_], Tail <: TypeList](
implicit f: Find[F, Tail]): Find[F, Head :: Tail] = null
implicit def isAtHead[F[_], Tail <: TypeList]: Find[F, F :: Tail] = null
}
}
object test {
trait C {
type Types <: TypeList
def add[G[_]](implicit a: TypeList.Add[Types, G]): C.Aux[a.Out] = ???
}
object C {
type Aux[List <: TypeList] = C { type Types = List }
}
object Test {
def apply[F[_]] = new C {
type Types = TypeList.Apply[F]
}
}
val t1 = Test[T1]
val t2 = t1.add[T2]
val t3 = t2.add[T2]
val t4 = t3.add[T3]
val t5 = t4.add[T2]
val t6 = t5.add[T1]
val t7 = t6.add[Option]
implicitly[t7.Types =:= (Option :: T3 :: T2 :: T1 :: Nil)]
val t8: C { type Types = (Option :: T3 :: T2 :: T1 :: Nil) } = t7
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment