Shapeless中Nat类型的限制


151

在无形状中,Nat类型表示一种在类型级别编码自然数的方法。例如,这用于固定大小的列表。您甚至可以在类型级别上进行计算,例如,将N元素列表追加到元素列表中,K并获取在编译时已知具有N+K元素的列表。

这种表示是否能够表示较大的数字(例如10000002 53),还是会导致Scala编译器放弃?


21
Miles 去年在NE Scala的演示中解决了这个问题,简短的回答是,可以使用Singleton类型在Scala(或至少在2.10中)以类型级别表示大量数字,但这可能不值得。目前,Shapeless 2.0仍使用Church编码,在放弃编译器之前,它将达到1,000个左右。
特拉维斯·布朗

3
今天晚些时候,我将尝试用更多的上下文来写一个答案。作为一个侧面说明,它不是太难整数单类型的工作,如果你需要更大的类型,级别的数字,例如参见我的博客文章在这里在无形单功能
特拉维斯·布朗

2
如果要对大型类型级别的数字进行算术运算,则可以考虑将它们实现为链接的位列表。
卡罗尔S

1
@KarolS我已经执行了该策略!我会很高兴,如果有人有兴趣将它有助于无形的,但它的毫无价值的,除非有人能帮助解决stackoverflow.com/questions/31768203/...
beefyhalo

2
看来stackoverflow.com/questions/31768203/…已解决,因此您可以贡献您的代码并使用自己的答案结束问题吗?
安德里·库巴

Answers:


17

我会自己尝试的。我很乐意接受Travis Brown或Miles Sabin的更好回答。

Nat当前不能用于表示大数

在当前的Nat实现中,该值对应于嵌套的shapeless.Succ []类型的数量:

scala> Nat(3)
res10: shapeless.Succ[shapeless.Succ[shapeless.Succ[shapeless._0]]] = Succ()

因此,要表示数字1000000,您将拥有一个嵌套1000000层深的类型,这肯定会炸毁scala编译器。从实验来看,当前的限制似乎是400,但是对于合理的编译时间,最好将其保持在50以下。

但是,有一种方法可以在类型级别对大整数或其他值进行编码,前提是您不想对它们进行计算。据我所知,您唯一可以做的就是检查它们是否相等。见下文。

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]进行位操作时,可用于强制执行相同的数组大小。


刚刚看到了这个答案,并且+1,这是一个很好的例子。值得一提的是,您可以提供诸如Shapeless之类的类型类ops.nat.Sum,它们可以看到两个类型级别的整数具有特定的总和,等等(它们只需要由宏提供即可)。
特拉维斯·布朗

1
是一个Concat类型类的示例,该类允许通过宏连接两个类型级别的字符串。用于汇总类型级别整数的类型类可能看起来非常相似。
Frank S. Thomas

5

Shapeless Nat使用Church编码在类型级别上对自然数进行编码。另一种方法是将自然值表示为位的类型级别HList。

检出稠密的物体,以无形状的样式实现此解决方案。

我已经有一段时间没有对此进行研究了,Lazy当scalac放弃时,它需要到处撒些无形的东西,但是这个概念很扎实 :)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.