Skip to content

Instantly share code, notes, and snippets.

@n4to4
Created September 5, 2016 04:07
Show Gist options
  • Save n4to4/57a4d9104e1a385fae935697e1e8830c to your computer and use it in GitHub Desktop.
Save n4to4/57a4d9104e1a385fae935697e1e8830c to your computer and use it in GitHub Desktop.
constraint-on-hlist-check-for-single-occurrence-of-a-type
/**
* http://stackoverflow.com/questions/39226147/constraint-on-hlist-check-for-single-occurrence-of-a-type/39226608#39226608
*/
import shapeless._, ops.hlist.{ToList}
trait T
case class TA() extends T
case class TB() extends T
trait UniqueTB[L <: HList] extends DepFn1[L] {
type Out = TB
def apply(l: L): TB
}
object UniqueTB {
def apply[L <: HList](implicit utb: UniqueTB[L]): UniqueTB[L] = utb
//def getTB[L <: HList](l: L)(implicit utb: UniqueTB[L]): TB = utb(l)
implicit def firstTB[T <: HList](implicit tl: ToList[T, TA]): UniqueTB[TB :: T] = new UniqueTB[TB :: T] {
def apply(l: TB :: T): TB = l.head
}
implicit def afterTB[T <: HList](implicit utb: UniqueTB[T]): UniqueTB[TA :: T] = new UniqueTB[TA :: T] {
def apply(l: TA :: T): TB = utb(l.tail)
}
}
object Main extends App {
// it should contain any arbitrary number of elements of type TA (from 0 to N);
// it should contain one and only one element of type TB.
UniqueTB[TB :: HNil]
UniqueTB[TA :: TB :: HNil]
UniqueTB[TA :: TB :: TA :: HNil]
UniqueTB[TB :: HNil]
import shapeless.test._
illTyped("UniqueTB[TA :: HNil]")
illTyped("UniqueTB[HNil]")
illTyped("UniqueTB[TB :: TB :: HNil]")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment