问题描述
在无形状中,Nat类型表示一种在类型级别编码自然数的方法。例如,这用于固定大小的列表。您甚至可以在类型级别上进行计算,例如将 N
元素列表添加到 K
元素列表中,并返回在编译时已知的列表具有 N + K
个元素。
In shapeless, the Nat type represents a way to encode natural numbers at a type level. This is used for example for fixed size lists. You can even do calculations on type level, e.g. append a list of N
elements to a list of K
elements and get back a list that is known at compile time to have N+K
elements.
此表示形式能够表示较大的数字吗,例如 1000000
或2 ,还是这会导致Scala编译器放弃?
Is this representation capable of representing large numbers, e.g. 1000000
or 2, or will this cause the Scala compiler to give up?
推荐答案
我会自己尝试。我很乐意接受Travis Brown或Miles Sabin的更好回答。
I will attempt one myself. I will gladly accept a better answer from Travis Brown or Miles Sabin.
Nat当前可以不用于表示大数字
Nat can currently not be used to represent large numbers
在当前的Nat实现中,该值对应于嵌套的shapeless.Succ []类型的数量:
In the current implementation of Nat, the value corresponds to the number of nested shapeless.Succ[] types:
scala> Nat(3)
res10: shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]] = Succ()
因此,要表示数字1000000,您将拥有嵌套1000000层深度的类型,这肯定会炸毁scala编译器。从实验来看,当前的限制似乎是400,但是对于合理的编译时间,最好将其保持在50以下。
So to represent the number 1000000, you would have a type that is nested 1000000 levels deep, which would definitely blow up the scala compiler. The current limit seems to be about 400 from experimentation, but for reasonable compile times it would probably be best to stay below 50.
但是,有一种方法可以对大整数或类型级别的其他值,前提是您不想对它们进行计算。据我所知,您唯一可以做的就是检查它们是否相等。见下文。
However, there is a way to encode large integers or other values at type level, provided that you do not want to do calculations on them. The only thing you can do with those as far as I know is to check if they are equal or not. See below.
scala> type OneMillion = Witness.`1000000`.T
defined type alias OneMillion
scala> type AlsoOneMillion = Witness.`1000000`.T
defined type alias AlsoOneMillion
scala> type OneMillionAndOne = Witness.`1000001`.T
defined type alias OneMillionAndOne
scala> implicitly[OneMillion =:= AlsoOneMillion]
res0: =:=[OneMillion,AlsoOneMillion] = <function1>
scala> implicitly[OneMillion =:= OneMillionAndOne]
<console>:16: error: Cannot prove that OneMillion =:= OneMillionAndOne.
implicitly[OneMillion =:= OneMillionAndOne]
^
例如在Array [Byte]上执行位操作时,强制执行相同的数组大小。
This could be used to e.g. enforce same array size when doing bit operations on Array[Byte].
这篇关于Shapeless中Nat类型的限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!