Преобразование Java в стандартный ML (SML) - PullRequest
0 голосов
/ 18 сентября 2011

Несколько моих друзей работают над простой рекурсивной функцией в SML, и до сих пор не смогли ее создать из-за отсутствия документации по SML и его синтаксису.Я пытался найти что-то сам, чтобы помочь им, но пока безуспешно.

Вот функция, которую я сделал в Java.Это работает, и я хотел бы преобразовать концепцию этой функции в SML.

 private static int shift;
 private static boolean firstRun = true;

 private static void crackThatThing(int clearText, int cryptoText) {
  if (firstRun) { // Make sure that the shift is only set once
   firstRun = false;
   shift = ((cryptoText % 10) - (clearText % 10)) % 10;
   crackThatThing((clearText / 10), (cryptoText / 10));
  } else {
   if (clearText > 0 && cryptoText > 0) {
    if (shift != ((cryptoText % 10) - (clearText % 10)) % 10) {
     // The shift value changed - this is not a valid encryption!
     System.out.println("This is not a valid encryption!");
    } else {
     // If the shift value is the same as before, continue with the next number
     crackThatThing((clearText / 10), (cryptoText / 10));
    }
   } else {
    // The encryption is valid
    System.out.println("The encryption is valid. The shift is: " + shift);
   }
  }
 }

Любые идеи?

Редактировать: Вот то, что я думаю, должно быть

Следующий код основан на абсолютно отсутствии предыдущего опыта работы с SML, и, поскольку я фактически удалил написанный код, он основан на битах, которые я могу запомнить.Я знаю, что это неправильный и очень вероятный отвратительный код, но, пожалуйста, потерпите меня на этом.

var notValid = "This is not a valid encryption!";
var valid = "The encryption is valid. The shift is: ";

var shift = 11; (* This is just to initialize it *)
var firstRun = true;

fun crackThatThing(clearText, cryptoText) =
if firstRun = true then
  firstRun = false andalso
  shift = ((cryptoText mod 10) - (clearText mod 10) mod 10) andalso
  crackThatThing(clearText div 10, cryptoText div 10)
else
  if clearText > 0 andalso cryptoText > 0 then
    if not (shift = ((cryptoText mod 10) - (clearText mod 10) mod 10)) then
      notValid
    else
      crackThatThing(clearText div 10, cryptoText div 10)
  else
    valid;

Ответы [ 2 ]

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

В сети существует множество книг и ресурсов (см. Ниже).

Вам нужны функции div и mod, а затем некоторые общие функциональные принципы, такие как рекурсия, чтобы решить эту проблему.Я не собираюсь давать вам код для этого, так как это еженедельное задание.Однако я буду более чем рад помочь по более конкретным вопросам, не связанным с этим заданием.

Ссылки


Все примеры, которые я видел, охватывают только очень простые операторы if-else

Тогда я бы осмелился сказать, что вы не выглядели правильно!См. Список ссылок выше, по крайней мере, некоторые из них содержат введение в SML на разных уровнях.

документация по SML нелепа по сравнению с другими языками.

Вы на самом деле не имеете в виду документацию, о которой говорите, но я могу только догадываться, что это не определение / комментарий.В любом случае кажется, что вы не понимаете, о чем говорите!

Мои друзья смогли "преобразовать" его в SML, используя две функции вместо одной, но это глупо делатькогда это должно быть действительно просто.

Действительно, и это действительно очень просто, когда вы понимаете функциональные принципы.Я снова буду рад дать советы по конкретным вопросам.

0 голосов
/ 20 сентября 2011

Глядя на ваш код, я вижу, что вы пытаетесь назначить переменные (вы написали что-то вроде firstRun = false, но = на самом деле является оператором равенства).Переменные в ML не могут быть назначены (так что «переменная» - это неправильное выражение; в действительности они в некотором смысле являются константами).Вы можете либо переписать свой код, чтобы не использовать мутации, либо использовать явные изменяемые ячейки (вызовите «ссылки»).В основном, для изменяемых ячеек вы используете функцию ref для создания изменяемой ячейки с заданным начальным значением.Вы используете оператор !, чтобы получить значение ячейки;и вы используете оператор := для изменения значения внутри ячейки.

Однако, я думаю, в вашем случае было бы плохой идеей использовать изменяемое глобальное состояние.Это плохой стиль, и кажется, что это сделает вашу функцию неиспользуемой более одного раза.Из того, что я вижу, вы используете глобальные переменные для отслеживания информации при выполнении рекурсивных вызовов вашей функции.Вместо этого вы можете определить внутреннюю функцию (локальную для внешней функции), которая выполняет рекурсию, и таким образом вы можете отслеживать вещи в локальных переменных внешней функции и / или передавать дополнительные переменные, когда вы повторяете внутреннюю функцию, не подвергая воздействиюсостояние в глобальной области видимости.

Также вы не объявляете переменные с var;Вы, вероятно, хотите val

...