Я пытаюсь реализовать умножение в SML с несколькими ограничениями. Я дал следующую add
функции:SML: Умножение с ограничениями
fun add (0 : int, m : int) : int = m
| add (n : int, m : int) : int = 1 + add(n-1, m)
Я пытаюсь написать функцию, что mult (m, n)
рекурсивно вычисляет произведение т и п, для любых двух натуральных чисел m
и n
. В вашей реализации может использоваться функция add
, упомянутая выше, и -
(вычитание), но она может не использовать +
или *
.
Вот моя попытка:
fun multiply(0 : int, m : int) = 0
| multiply(n : int, 0 : int) = 0
| multiply(1 : int, m : int) = m
| multiply(n : int, 1 : int) = n
| multiply(~1 : int, m : int) = ~m
| multiply(n : int, ~1 : int) = ~n
| multiply(n : int, m : int) =
if (n > 0 andalso m > 0) then
add(add(0, n), multiply(n, m - 1))
else
if (n < 0 andalso m < 0) then
multiply(~n, ~m)
else
if (n < 0 andalso m > 0) then
n - multiply(n, m - 1)
(* n > 0 and m < 0 *)
else
m - multiply(m, n - 1);
Он работает, когда n
и m
оба положительны или оба отрицательные, но не тогда, когда один положительный, а другой отрицательный, но я не могу показаться, чтобы выяснить, моя ошибка. Например,
multiply(3, ~10)
оценивает по: 0
. Поэтому я считаю, что мой рекурсивный вызов достигает 0
и вызывает его оценку 0
. Сказав это, мои базовые дела позаботятся об этом, поэтому я не уверен, как это будет возможно.
Идеи?
Возможно изменить 'м - умножить (т, п - 1);' на 'м - умножить (п - 1, м); Рекурсия может быть запутана? Прошло 4 года с тех пор, как я коснулся SML, так что извините, я не могу быть более полезным – Parker
@Parker Почему вы предлагаете это? (Не говорите, что это неправильно, но заинтересованы в ваших рассуждениях тоже) – bclayman
Просто быстрый взгляд выглядит так: вы обрабатываете вещи, основываясь на двух положительных или отрицательных значениях, если вы продолжаете рекурсировать, а n и m постоянно меняются, это может испортить логики. Как функция всегда ожидает (n, m), но вы передаете ее (m, n). Опять же, я, возможно, забыл функции SML – Parker