2016-06-02 1 views
2

я обнаружил weired вещи:OCaml: List.iter начинается с следующим элементом после матча

В моем коде, я хочу, чтобы вывести данные из списка, который содержит элементы особого типа, состоящий из другога тип и name.

Мне никогда не нужен такой код раньше, поэтому я не знаю, почему он не работает или запрещен или что-то в этом роде.

List.iter(
    fun x -> (
     fprintf oc "("; 
     fprintf oc "asdf"; 
     match x.kind with 
     |Id -> fprintf oc "Id" 
     |Op -> fprintf oc "Op" 
     |Test -> fprintf oc "Test" 
     ; 
     fprintf oc "fdsa"; 
     fprintf oc "%s" x.name; 
     fprintf oc "),"; 
    ) 
)list; 

asdf и fdsa являются тестовыми выходами, чтобы увидеть, где проблема. осов моего выхода канал для записи в файл, остальное должно быть тихо самоуправление объяснения для OCaml-профессионалов, как вы :)

К сожалению, я получаю только результат, как эти: (asdfId(asdfOp(asdfId, так что кажется, что выполнение останавливается после матча, и он продолжает следующий элемент списка.

Ожидаемый результат будет (asdfIdfdsatest1),(asdfOpfdsatest2) ...

Я не могу просто переместить x.name к вершине, так как мне нужна закрывающая скобка

Что я делаю неправильно, я упускаю ошибка? Кто-нибудь знает, как выводить мои данные?

+1

Используйте соответствующий код OCaml отступы, чтобы избежать таких ошибок, таких как ocaml-mode, tuareg-mode или ocp-indent. Они отступывают строку 'fprintf oc 'fdsa"; 'иначе, чем ваше намерение. – camlspotter

ответ

6

В OCaml match имеет больший приоритет, чем ;. Итак, вам нужно обернуть ваш match в пару круглых скобок.

Давайте попробуем следующее верхнего уровня:

> match 0 with 
    | 0 -> print_string "zero " 
    | _ -> print_string "non-zero"; 
    print_endline "42";; 

Output: zero 

А теперь давайте добавим скобки вокруг match выражения:

> (match 0 with 
    | 0 -> print_string "zero " 
    | _ -> print_string "non-zero"); 
    print_endline "42";; 

Output: zero 42 

примечание стороны: в реальной жизни лучше использовать выражение if для такого рода «сопоставление образцов» для целых чисел.

0

Стандартный способ отступы ваш код:

List.iter (fun x -> 
    fprintf oc "("; 
    fprintf oc "asdf"; 
    match x.kind with 
    |Id -> fprintf oc "Id" 
    |Op -> fprintf oc "Op" 
    |Test -> fprintf oc "Test" 
     ; 
     fprintf oc "fdsa"; 
     fprintf oc "%s" x.name; 
     fprintf oc "),"; 
) list; 

Здесь вы можете увидеть, что последние 3 инструкции выполняются только в 3-й ветви.

Чтобы решить эту проблему, вы можете переписать код таким образом (первый способ это обычный один, от того, что я видел:

List.iter (fun x -> 
    fprintf oc "("; 
    fprintf oc "asdf"; 
    begin match x.kind with 
    |Id -> fprintf oc "Id" 
    |Op -> fprintf oc "Op" 
    |Test -> fprintf oc "Test" 
    end; 
    fprintf oc "fdsa"; 
    fprintf oc "%s" x.name; 
    fprintf oc "),"; 
) list; 

или

List.iter (fun x -> 
    fprintf oc "("; 
    fprintf oc "asdf"; 
    (match x.kind with 
    |Id -> fprintf oc "Id" 
    |Op -> fprintf oc "Op" 
    |Test -> fprintf oc "Test"); 
    fprintf oc "fdsa"; 
    fprintf oc "%s" x.name; 
    fprintf oc "),"; 
) list; 

 Смежные вопросы

  • Нет связанных вопросов^_^