Я пытаюсь изучить возможности с уточнением (и бесформенностью), чтобы улучшить проверку типов.
Я хотел бы представить типом некоторые ограничения интервала или размера.
Итак, с уточнением я могу писать такие вещи:
type Name = NonEmpty And MaxSize[_32]
type Driver = Greater[_15]
case class Employee(name : String @@ Name, age : Int @@ Driver = refineLit[Driver](18))
Но я хотел бы выразить ограничения с помощью натуральных чисел большего размера.
type BigNumber = Greater[_1000]
Это не работает, потому что _1000
не определено. Последний уже определенный _22
Я могу с бесформенным Succ
сделать свой, но очень громоздкий.
Пример :
type _25 = Succ[Succ[Succ[_22]]]
type _30 = Succ[Succ[Succ[Succ[Succ[_25]]]]]
type _40 = Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[_30]]]]]]]]]]
type _50 = Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[_40]]]]]]]]]]
type _60 = Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[_50]]]]]]]]]]
type _70 = Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[_60]]]]]]]]]]
type _80 = Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[_70]]]]]]]]]]
type _90 = Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[_80]]]]]]]]]]
type _100 = Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[Succ[_90]]]]]]]]]]
// etc.
Есть ли лучший способ выразить такие ограничения или сделать _1000
более эффективным способом? Есть ли что-то, что я бы пропустил?
Изменить :
Я попробовал предложение Трэвиса:
val thousand = shapeless.nat(1000)
Но эта строка вызывает StackOverflowError
во время компиляции (при расширении макроса). Если я попробую с меньшим числом, все в порядке.
val limit = shapeless.nat(50)
type BigNumber = Greater[limit.N]
case class TestBigNumber(limit : Int @@ BigNumber)
В моей среде StackOverflowError возникает для чисел больше 400.
Более того, с этим кодом компиляция никогда не заканчивалась (с использованием sbt):
val n_25 = shapeless.nat(25)
type _25 = n_25.N
val n_32 = shapeless.nat(32)
type _32 = n_32.N
val n_64 = shapeless.nat(64)
type _64 = n_64.N
val thousand = nat(1000); type BigNumber = Greater[thousand.N]
, что немного лучше. Я думал, что можно написать что-то вродеNat.`100`.N
, но, возможно, мне это показалось. - person Travis Brown   schedule 01.07.2015val thousand = nat(1000)
, как в eclipse, так и в sbt - person volia17   schedule 01.07.2015