В бесформенном, тип Nat представляет собой способ кодирования натуральных чисел на уровне типа. Это используется, например, для списков фиксированного размера. Вы даже можете выполнять вычисления на уровне типа, например. добавьте список элементов N
в список элементов K
и верните список, который во время компиляции известен вовремя, чтобы иметь N+K
элементы.
Является ли это представление способным представлять большие числа, например. 1000000
или 2 53 или это приведет к отказу компилятора Scala?
Я попробую сам. Я с радостью согласимся на лучший ответ от Трэвиса Брауна или Майлза Сабина.
В настоящее время 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].
ops.nat.Sum
's ops.nat.Sum
, которые свидетельствовали бы о том, что два целых числа уровня типа имели определенную сумму и т. Д. (Они просто должны были бы быть предоставлены макросом).
Concat
типа Concat
который позволяет объединять две строки уровня типа через макрос. Класс типов для суммирования целых чисел на уровне типов, вероятно, будет выглядеть очень похоже.
Shapeless Nat
кодирует натуральные числа на уровне типа, используя кодировку. Альтернативный метод состоит в том, чтобы представить naturals как HList уровня типа бит.
Отъезд dense, который реализует это решение в бесформенном стиле.
Я не работал над этим через какое-то время, и ему нужно разбрызгивать бесформенную Lazy
здесь и там, когда scalac отказывается, но концепция прочная:)