2013-02-19 2 views
2

Я написал myPercolation.ml.Почему ocamlc говорит, что я не понял {}, а я нет?

open MyUnionFind 

module type MyPercolationSig = sig 
    type percolation 
    val create_percolation : int -> percolation 
    val open_site : percolation -> int -> int -> unit 
    val is_open : percolation -> int -> int -> bool 
    val is_full : percolation -> int -> int -> bool 
    val can_percolates : percolation -> bool 
end 

module MyPercolation : MyPercolationSig = struct 

    exception IndexOutOfBounds;; 

    type percolation = 
     {n : int; 
     sites: bool array; 
     union : MyUnionFind.union_find};; 

    let create_percolation n = 
    {n = n; sites = Array.make (n*n) false; union = MyUnionFind.create_union (n*n)};; 

    let open_site p i j = 
    let {n;_;union} = p 
    in 
    if not (is_open p i j) then 
     begin 
    sites.(index_of n i j) <- true; 
    if i - 1 >= 1 && i - 1 <= n && is_open n (i-1) j then 
     MyUnionFind.union union (index_of n i j) (index_of n (i-1) j) 
    else if i + 1 >= 1 && i + 1 <= n && is_open n (i+1) j then 
     MyUnionFind.union union (index_of n i j) (index_of n (i+1) j) 
    else if j - 1 >= 1 && j - 1 <= n && is_open n i (j-1) then 
     MyUnionFind.union union (index_of n i j) (index_of n i (j-1)) 
    else if j + 1 >= 1 && j + 1 <= n && is_open n i (j+1) then 
     MyUnionFind.union union (index_of n i j) (index_of n i (j+1)) 
     end;; 

    let index_of n i j = n * (i - 1) + j;; 

    let is_open {n;sites;_} i j = 
    if i < 1 || i > n || j < 1 || j > n then 
     raise IndexOutOfBounds 
    else 
     sites.(index_of n i j);; 

    let is_full {n;_;union} i j = 
    let rec is_connected_top j' = 
     if j = 0 then false 
     else 
    if MyUnionFind.is_connected union (index_of n i j) (index_of n 0 j') then true 
    else is_connected_top (j'-1) 
    in is_connected_top n;; 

    let can_percolates p = 
    let {n;_;_} = p 
    in 
    let rec is_full_bottom j = 
     if j = 0 then false 
     else 
    if is_full p n j then true 
    else is_full_bottom (j-1) 


end 

Пожалуйста, игнорируйте пакету MyUnionFind пакет. Это просто самодельная реализация для алгоритма union-find.

когда я пытаюсь скомпилировать myPercolation.ml, я получил такую ​​ошибку:

$ ocamlc -c myPercolation.ml 
File "myPercolation.ml", line 25, characters 11-12: 
Error: Syntax error: '}' expected 
File "myPercolation.ml", line 25, characters 8-9: 
Error: This '{' might be unmatched 

Я думаю, что ошибка говорит о let {n;_;union} = p в функции let open_site p i j.

Я прочитал эту строку и весь код много раз, но я до сих пор не вижу в этой строке несоответствия {}.

может кто-нибудь помочь?

ответ

3

Выражение let {n; _; union} = p не совсем сформировано OCaml. Я думаю, что вы хотите let {n; union} = p. Нельзя упоминать о способах обработки полей, которые вам не нужны в шаблоне записей.

Update:

Как rgrinberg указывает, гораздо лучше описать проблему в том, что _ должен выглядеть как последнее поле. Вот почему компилятор ожидает увидеть } после этого. Может быть, хороший стиль включает _ в качестве индикатора, который вы намеренно сопоставляете только подмножеству полей записи. Фактически вы можете включить параметр компилятора, который проверяет это.

Update 2:

Предупреждение о неполных шаблонов записей предупреждает номер 9, а также связан с буквой R. Вот как использовать R:

$ ocaml -w +R 
     OCaml version 4.00.0 

# type r = { a: int; b: char };; 
type r = { a : int; b : char; } 
# let {a} = {a=3; b='x'} in a;; 
Warning 9: the following labels are not bound in this record pattern: 
b 
Either bind these labels explicitly or add '; _' to the pattern. 
- : int = 3 

из командной строки Синтаксис для компилятора одинаковый.

+0

'{n; union} 'даст предупреждение компилятора, я думаю. Если вы считаете, что предупреждение компиляции не нужно, вы можете использовать '{n; союз; _} ', но подчеркивание должно быть последним. – rgrinberg

+0

Я не вижу никаких предупреждений с настройками по умолчанию для OCaml 4.00.0. Но вы правы, '_' разрешен, если это последнее поле. –

+1

Предупреждения должны быть включены, я думаю. См .: http://caml.inria.fr/pub/docs/manual-ocaml-4.00/manual021.html#toc78 – rgrinberg

4

Другая возможная ошибка: {n;_;_} должно быть {n;_} Нужно только подчеркнуть 1. Подумайте об этом, как в шаблоне _.

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