Suppose I have a method without params. How can I determine a length of type parameter?
def func[T <: HList]: Nat = {
// some magic
}
You can use ops.hlist.Length
operation to calculate the Nat
length of an HList
.
Also, getting it as an opaque Nat
is not very useful, because you lose all the type-level information about the actual number. So you have to get the exact Nat
type from the function:
import shapeless._
import shapeless.ops.hlist.Length
def func[T <: HList](implicit len: Length[T]): len.Out = len()
Usage:
scala> natLen[Int :: String :: HNil]
res1: shapeless.Succ[shapeless.Succ[shapeless._0]] = Succ()
Getting the length as an Int
seems more tricky. It seems you can't use ops.nat.ToInt
, because it would require a N <: Nat
type parameter and basically make it useless:
def uselessIntLen[T <: HList, N <: Nat](implicit
len: Length.Aux[T, N],
toInt: ToInt[N]
): Int = toInt()
I've found the following workaround using HKernel
(of course, it's also possible to write a new typeclass IntLength
manually). Maybe someone can help with a more direct built-in method:
import shapeless.ops.hlist.HKernelAux
def intLen[T <: HList](implicit ker: HKernelAux[T]): Int = ker().length
Usage:
scala> intLen[Int :: String :: HNil]
res2: Int = 2