Shapeless 中 Nat 类型的限制 [英] Limits of Nat type in Shapeless

查看:21
本文介绍了Shapeless 中 Nat 类型的限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 shapeless 中,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 或 253,还是会导致 Scala 编译器放弃?

Is this representation capable of representing large numbers, e.g. 1000000 or 253, 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 类型的限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆