Ocaml вложен, если без else

Возможно ли иметь вложенные if без операторов else. Я написал следующую бесполезную программу для демонстрации вложенных ifs. Как мне это исправить, чтобы это было правильно с точки зрения синтаксиса. строки 5 и 6 дают ошибки.

let rec move_helper b sz r = match b with
    [] -> r
    |(h :: t) ->
        if h = 0 then
            if h - 1 = sz then h - 1 ::r
            if h + 1 = sz then h + 1 ::r
        else move_helper t sz r
;;

let move_pos b = 
    move_helper b 3 r
;;

let g = move_pos [0;8;7;6;5;4;3;2;1]

person rightDrop    schedule 30.03.2015    source источник
comment
Если бы вы не демонстрировали вложенные операторы if, вы могли бы выполнить сопоставление с (h, h-sz). В реальном коде не используйте вложенные операторы if в качестве сопоставления с образцом, или взаимно рекурсивные функции намного лучше справляются со структурированием. программа.   -  person Michaël Le Barbier    schedule 31.03.2015


Ответы (2)


У вас не может быть if без else, если только результат выражения не имеет тип unit. Это не относится к вашему коду, поэтому это невозможно.

Вот пример, где результат равен unit:

let f x =
    if x land 1 <> 0 then print_string "1";
    if x land 2 <> 0 then print_string "2";
    if x land 4 <> 0 then print_string "4"
person Jeffrey Scofield    schedule 30.03.2015
comment
Я попытался заключить оба утверждения с помощью (); раньше, но затем я получаю синтаксическую ошибку в строке 7 (иначе рекурсивный вызов) - person rightDrop; 30.03.2015
comment
Ну, это другой вопрос. Вообще говоря, вы должны быть осторожны со скобками при смешивании вложенных if и let. Это мой опыт. Но ваш код читается как императивный код. Я подозреваю, что это первое препятствие, которое нужно преодолеть. - person Jeffrey Scofield; 30.03.2015
comment
Я удалил императивный код и заменил его рекурсивной функцией. Единственным недостатком была одна дополнительная функция и дополнительный код. Теперь он работает нормально. - person rightDrop; 31.03.2015

Вы должны понимать, что if ... then такое же выражение, как и любое другое. Если else отсутствует, его следует понимать как if ... then ... else () и, следовательно, иметь тип unit. Чтобы подчеркнуть тот факт, что это выражение, предположим, что у вас есть две функции f и g типа, скажем, int → int. Ты можешь написать

(if test then f else g) 1

Вы также должны понимать, что x :: r не вообще не изменяет r, он создает новый список, помещая x перед r (хвост этого списка является общим со списком r). В вашем случае не понятна логика: каков результат, когда h=0 но два if терпят неудачу?

let rec move_helper b sz r = match b with
  | [] -> r
  | h :: t ->
     if h = 0 then
       if h - 1 = sz then (h - 1) :: r
       else if h + 1 = sz then (h + 1) :: r
       else (* What do you want to return here? *)
     else move_helper t sz r
person ChriS    schedule 30.03.2015