Я пытаюсь реализовать bigdecimal в Идрисе. У меня это до сих пор:реализация BigDecimal в idris
-- a big decimal has a numerator and a 10^x value
-- it has one type for zero,
--TODO the numerator can't be zero for any other case
--TODO and it can't be divisible by 10
data BigDecimal : (num : Integer) -> (denExp : Integer) -> Type where
Zero : BigDecimal 0 0
BD : (n : Integer) -> (d : Integer) -> BigDecimal n d
Я хотел был бы установить ограничения, обозначенные "TODO" выше. Тем не менее, я просто изучаю Идрис, поэтому я даже не уверен, что это ограничение - хорошая идея или нет.
В общем, я пытаюсь создать инструмент расчета налогов, способный вычислять несколько (крипто) валют с использованием произвольной точности. Я бы хотел, чтобы потом попытался использовать этот метод, чтобы доказать некоторые свойства программы.
Итак, мои вопросы:
- Является ли это хорошее дизайнерское решение, чтобы попытаться обеспечить соблюдение ограничений я заданные?
- Возможно ли это ограничение в Идрисе?
- Является ли это хорошей реализацией BigDecimal в Идрисе?
Edit: Я думал, что-то вроде "BD: (п: Integer) -> ((п = 0) = Void) -> (d: Integer) -> BigDecimal-й", так что вы должны доказательство того, что n не равно нулю. Но я действительно не знаю, хорошая ли это идея или нет.
Редактировать 2: В ответ на комментарий Cactus было бы лучше?
data BigDecimal : Type where
Zero : BigDecimal
BD : (n : Integer) -> (s : Integer) -> BigDecimal
Как правило, BigDecimals состоят из BigInteger для цифр (для немасштабированного значения) и шкала или показатель, указывающий, где десятичная точка должна быть (это может быть отрицательное значение, так что вы можете представить очень большие значения тоже). К сожалению, я не знаю Идриса, поэтому я не могу сказать, как это сделать на этом языке. Ваша идея с числителем звучит скорее как BigFraction или BigRational. Это немного осложнит ситуацию, ИМО. –
На самом деле я использую ту же идею, о которой вы говорите. Я, вероятно, не должен был называть его числителем, но я думал (числитель)/(10 ** (показатель знаменателя)). – redfish64
Тогда именование действительно странно. Ваш числитель - это значение без масштабирования, которое я имел в виду, и ваш показатель знаменателя - это масштаб. Таким образом, значение 1.000 представлено как немасштабированное значение 1000 и шкала 3. Просто убедитесь, что вы увеличиваете или уменьшаете правильность при добавлении или вычитании и корректируете масштаб при умножении или делении. Кроме того, если вы разделите, масштабируйте числитель на нужную точность и округлите результат. То есть с точностью 10, умножьте числитель на 10 ** 10 и затем разделите, в противном случае 1/10 может привести к 0 вместо 0.1000000000. –