Цикл SML / NJ - PullRequest
       4

Цикл SML / NJ

3 голосов
/ 25 сентября 2011

Я действительно новичок в SML и не могу понять, как получить ответ на этот вопрос;

Это выглядит примерно так: 3 ^ 4 <32, но 3 ^ 5> 32, поэтому мой ответ 4 (степень 3), аналогично, если у меня есть числа 4 и 63, то 4 ^ 2 <63, но 4 ^ 3> 63 поэтому мой ответ 2 (степень 4).

Я придумал следующий код

val log (b, n) =
    let
        val counter = ref b
        val value = 0
    in
        while !counter > n do 
        ( counter := !counter*b 
          value := !value + 1)
    end;

Таким образом, здесь значение - это то, что мне нужно в качестве ответа, но я получаю много ошибок. Я знаю, что я неправ во многих местах. Любая помощь будет оценена.

Возможно, я могу сделать это обычным способом ML, но я хочу научиться и нечистому ML ...

fun loghelper(x,n,b) = if x>n then 0 else (1+loghelper((x*b),n,b)); 
fun log(b,n) = loghelper(b,n,b);

Хорошо, наконец, вот правильный код для цикла while, и он также работает;

      fun log (b, n) =
            let
               val counter = ref b
               val value = ref 0
            in
               while (!counter <= n) do 
               (counter := !counter*b; 
                value := !value + 1);
               !value
            end;

1 Ответ

3 голосов
/ 26 сентября 2011

У вас есть несколько проблем в вашем коде:

Ошибка:

  • Вместо val log (b, n) = должно быть fun log (b, n) =. fun - это удобный синтаксис, который позволяет легко определять функции. Если бы вы хотели написать это с помощью val, вы бы написали: val log = fn (b, n) => (это усложняется в случае рекурсивных функций или функций с несколькими аргументами с карри) *
  • Вам нужно использовать точку с запятой для разделения двух обязательных операторов: ( counter := !counter*b; value := !value + 1)
  • value должен быть ref: val value = ref 0

Логика:

  • Ваша функция ничего не возвращает. Цикл while имеет тип устройства, поэтому ваша функция возвращает () (устройство). Вы, вероятно, хотите вернуть !value. Для этого вам нужно добавить точку с запятой после всего цикла while, а затем написать !value
  • Ваше условие цикла while не имеет смысла. Кажется наоборот. Вы, вероятно, хотите while !counter <= n do
  • Ваш базовый случай не верен. Либо value должно начинаться с 1 (поскольку counter начинается с b, а b равняется b до первой степени); или counter должно начинаться с 1 (поскольку b до нулевой степени 1). Та же проблема существует с вашей функциональной версией.
...