Пределы типа Nat в Shapeless

В бесформенном, тип Nat представляет собой способ кодирования натуральных чисел на уровне типа. Это используется, например, для списков фиксированного размера. Вы даже можете выполнять вычисления на уровне типа, например. добавьте список элементов N в список элементов K и верните список, который во время компиляции известен вовремя, чтобы иметь N+K элементы.

Является ли это представление способным представлять большие числа, например. 1000000 или 2 53 или это приведет к отказу компилятора Scala?

Ответ 1

Я попробую сам. Я с радостью согласимся на лучший ответ от Трэвиса Брауна или Майлза Сабина.

В настоящее время Nat может не использоваться для представления больших чисел

В текущей реализации Nat это значение соответствует количеству вложенных бесформенных типов .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].

Ответ 2

Shapeless Nat кодирует натуральные числа на уровне типа, используя кодировку. Альтернативный метод состоит в том, чтобы представить naturals как HList уровня типа бит.

Отъезд dense, который реализует это решение в бесформенном стиле.

Я не работал над этим через какое-то время, и ему нужно разбрызгивать бесформенную Lazy здесь и там, когда scalac отказывается, но концепция прочная:)