2012-01-20 12 views
3

を定義するにもかかわらず、私はこのように定義された関数があります - 私はとしてそれを定義していてもOCamlのネストされたパターン - 例外パターン

let test_func lis = 
    match lis with h::t -> 
    match h with h2::t2 -> 
     h2 
    | [] -> 
     [] 
    | [] -> 
    [];; 

コンパイルすると、私はこの機能は[]のパターンと一致しないという警告を取得します2番目のケース!私は括弧を有する第二の一致ステートメントを囲むことにより、この問題を解決することができることを見出した:

let test_func lis = 
    match lis with h::t -> 
    (match h with h2::t2 -> 
     h2 
    | [] -> 
     []) 
    | [] -> 
    [];; 

が、これが必要な理由私は思っていました。また、トップレベルの一致ステートメントで1番目と2番目のケースを入れ替えても動作します。

let test_func lis =  
    match lis with [] -> 
    [] 
    | h::t -> 
    match h with h2::t2 -> 
     h2 
    | [] -> 
     [];; 

ありがとう!私たちはあなたのコードのインデントを修正した場合

+1

私は常に括弧の代わりに 'begin ... end'を使うことを勧めます。コードブロックを識別することははるかに簡単です。 – nlucaroni

+0

チップをありがとう!私はそれらのキーワードに精通していませんでした。 –

答えて

8

、それは次のようになります。あなたはそれを見れば

let test_func lis = 
    match lis with h::t -> 
    match h with h2::t2 -> 
     h2 
    | [] -> 
     [] 
    | [] -> 
     [];; 

、それは| [] -> []第一及び第二の間に違いはありませんことが明らかになる。したがって、コンパイラは、2番目のものが外側のmatch-statementに属し、内側のmatch-statementに属さないことを意図していることを知る方法がありません。したがって、最初に| [] -> []の後に内部一致ステートメントが終了することをコンパイラに伝えるためにかっこにする必要があります。

2番目のバージョンでは、最初の| [] -> []は明らかに外側のmatch-statementに属しています。内側のmatch-statementは、プログラムのさらに遠くまで表示されないからです。だからあいまいさがなく、かっこは必要ありません。

+0

偉大な答えをありがとう! –

関連する問題