The length of HList type paremeter in terms of Nat

会有一股神秘感。 提交于 2019-12-21 21:31:07

问题


Suppose I have a method without params. How can I determine a length of type parameter?

def func[T <: HList]: Nat = {
  // some magic
}

回答1:


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


来源:https://stackoverflow.com/questions/38923040/the-length-of-hlist-type-paremeter-in-terms-of-nat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!