2011-01-12 9 views
0

私は約6ヶ月間F#を書いてきましたが、私は説明できない振る舞いに出くわしました。私はいくつかのコードを下に煮詰めました。F# - パターンマッチングがユニオンを区別するときの奇妙な振る舞い

私はレコードタイプrec1とrec2を使用して定義された階層と、可能な値CaseAとCaseBを持つ区別された共用体型を持っています。私はdu_recオプションの型を取る関数( 'mynewfunc')を呼び出しています。内部的には、この関数は階層を処理する再帰関数を定義します。

私は、Noneオプションの値を渡して階層のルートを表現しています(実際には、この関数はファイルから階層を逆シリアル化しています)。

以下のコードを実行すると、 "failwith"無効な親 ""コード行が表示されます。私は、これがなぜであるのか理解できません。なぜなら、渡されるNone値は、外側のパターンマッチングのNoneの場合と一致しなければならないからです。

いずれかのコメントのセットを削除すると、コードが機能します。これは私にとって致命ではありません - 私はなぜこれが起こっている知らずに少し不快に感じる(私はF#のを理解していたと思った)

ジェームズ

すべての回答を事前に

おかげ

type rec2 = 
    { 
    name : string 
    child : rec1 option 
    } 
and rec1 = 
    { 
    name : string ; 
    child : rec2 option 
    } 
and du_rec = 
    | Case1 of rec1 
    | Case2 of rec2 


let mynewfunc (arg:du_rec option) = 
    let rec funca (parent:du_rec option) = 
     match parent with 
     | Some(node) -> 
      match node with 
      | Case2(nd) -> 
       printfn "hello" 
      (* | Case1(nd) -> 
       printfn "bye bye" *) 
      | _ -> 
       failwith "invalid parent" 
     | None -> 
       // printfn "case3" 
       () 
     funcb(None) 
    and funcb (parent: du_rec option) = 
     printfn "this made no difference" 
    let node = funca(arg) 
    () 

let rootAnnot = mynewfunc(None) 
+0

du_recで 'と'を使う必要はありません。これが役立つかどうかは分かりません。 – gradbot

+3

元のコードは少し変形してコンパイルされませんでした。コンパイルするように修正しました。私も私のマシンでそれをテストしました、それは正常に動作するようです。 F#とFSIのバージョン番号を使用している環境(モノはおそらく?)を記述できますか? – Juliet

+0

競合するフィールド名があることに注意してください。私はあなたがこれから何を期待していたのかを理解していません。 –

答えて

3

コメントに基づいて、これはデバッガでの悪い経験です(ハイライト表示では、制御フローはそうでない場所にあることが示唆されています)。コードはあなたが期待することを行います。

(F#コンパイラは、デバッグの経験を向上させるためにPDBSに生成されたその配列の点を、改善することができた場所の数がありますが、私たちは、将来のリリースでは、このを見ていると思います)

+0

ブライアンに感謝します。次のコードはさらに短く、デバッガも混乱させます:match 2 with | 1 - > printfn "one" | _ - > () – Jimmy