Created
September 5, 2016 04:07
-
-
Save n4to4/57a4d9104e1a385fae935697e1e8830c to your computer and use it in GitHub Desktop.
constraint-on-hlist-check-for-single-occurrence-of-a-type
This file contains 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
/** | |
* 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