Using Peter Neyens's helpful answer, I tried to create an X
class that only consists of Nat
's less than or equal to 2.
import shapeless._
import shapeless.ops.nat._
import shapeless.nat._
case class X[A <: Nat](values: List[A])(implicit ev: LTEq[A, _2])
The following works:
scala> X( List(_1, _1, _1) )
res6: X[shapeless.nat._1] = X(List(Succ(), Succ(), Succ()))
But when I used different Nat
's, i.e. _1
and _2
, I got a compile-time error:
scala> X( List(_1, _2) )
<console>:23: error: could not find implicit value for parameter ev:
shapeless.ops.nat.LTEq[shapeless.Succ[_ >: shapeless.Succ[shapeless._0]
with shapeless._0 <: Serializable with shapeless.Nat],shapeless.nat._2]
X( List(_1, _2) )
^
Then I tried:
scala> case class X(values: List[_ <: Nat])
defined class X
which works for sub-classes
of Nat
, but it's not bounded by <= 2
:
scala> X(List(_1, _2, _3))
res8: X = X(List(Succ(), Succ(), Succ()))
How can I write my above X
that has a List of Nat
's that fall in the range of 0 to 2
?
My immediate thought is to use an Algebraic Data Type for MyZero
, MyOne
, and MyTwo
, but not sure that's the cleanest way.
Lastly, it seems to me that X
's requirement to have a type parameter is unnecessary. Can it either be inferred or left out in an implementation of my desired X
?