2012-02-03 8 views
0

I持っている2つのネストされた差別組合:F番号:労働組合を区別して一致する入れ子

type ServiceTypes = 
    | Contexts 
    | Context of int 
    | Producers 

type ServiceActions = 
    | Get of ServiceTypes 
    | Update of ServiceTypes 

とネスト一致ステートメント:

let s_action = match action with 
       | Get(stype) -> sprintf "Get%s" (match stype with 
               | Contexts -> sprintf "Contexts" 
               | Context(id) -> (sprintf "Context/%d" id)) 
               | _ -> raise (RequestException("get")) 
       | Update(stype) -> sprintf "Update%s" (match stype with 
                 | Producers -> (sprintf "Producers") 
                 | _ -> raise (RequestException("update"))) 
目標は、呼び出しはのように見えるとのリクエスト文字列を構築することです

そのreq.Send(Update Producers)。私は、このルールは最初match stype Iに

  • に一致することはありません取得Update(stype)

    1. :とにかく、私は理解していない理由で

      は、コンパイラは私に2回の警告を与えますget この式で不完全なパターンが一致します。たとえば、値「プロデューサーズ」は、パターンによってカバーされていないケースを示すことがあります。

    なぜこの2つの警告が表示されるのですか?私はマッチングの仕方で何かを忘れましたか?

  • 答えて

    5

    あなたの閉じ括弧は間違った場所にあります。

    | Context(id) -> (sprintf "Context/%d" id)) 
    | _ -> raise (RequestException("get")) 
    

    私は(この場合に実際にあるすべてのかっこ)すべて余分な括弧を取り除くでしょう明確化のために、実際に

    | Context(id) -> (sprintf "Context/%d" id) 
    | _ -> raise (RequestException("get"))) 
    

    次のようになります。

    let s_action = 
        match action with 
        | Get stype -> match stype with 
             | Contexts -> "Contexts" 
             | Context id -> sprintf "Context/%d" id 
             | _   -> RequestException "get" |> raise 
             |> sprintf "Get%s" 
        | Update stype -> match stype with 
             | Producers -> "Producers" 
             | _   -> RequestException "update" |> raise 
             |> sprintf "Update%s" 
    

    個人的に私はこれをよりわかりやすく見つけましたが、 YMMVのようなものです。

    +0

    Arf ...私はパターンマッチングを理解していないと思った:P少なくともそれはただの文法ミスだった。余分な括弧を取り除く方法についての素晴らしいデモ(私はコードを更新しました)。あなたのお時間をありがとうございました! –

    1

    間違った時点でparathesesを閉じているので、あなたのコードは、実際に次のようになります。

    let s_action = 
        match action with 
        | Get(stype) -> sprintf "Get%s" (match stype with 
                | Contexts -> sprintf "Contexts" 
                | Context(id) -> (sprintf "Context/%d" id)) 
        | _ -> raise (RequestException("get")) (* Closing parenthesis should be here *) 
        | Update(stype) -> sprintf "Update%s" (match stype with 
                 | Producers -> (sprintf "Producers") 
                 | _ -> raise (RequestException("update"))) 
    

    もちろん、あなたが最初match stype withProducersをカバーしていないと、最後のパターンUpdate(stype)が前のパターンによる一致したことはありません見ることができます_したがって、すべてのコンパイラの警告は正当です。

    あなたはパラチェスを使いすぎているようです。ネストされた一致表現が時々保証され

    let s_action = 
    match action with 
    | Get stype -> sprintf "Get%s" <| match stype with 
                | Contexts -> sprintf "Contexts" 
                | Context id -> sprintf "Context/%d" id 
                | _ -> raise <| RequestException "get" 
    | Update stype -> sprintf "Update%s" <| match stype with 
                 | Producers -> sprintf "Producers" 
                 | _ -> raise <| RequestException "update" 
    
    9

    ながら私はあなただったら、この特定のケースでは、私は、より読みやすい単一レベルの試合を記述します:ここにクリーンアップバージョンです

    let s_action = 
        match action with 
        | Get Contexts  -> "GetContexts" 
        | Get (Context id) -> sprintf "GetContext/%d" id 
        | Update Producers -> "UpdateProducers" 
        | Get _ -> raise (RequestException "get") 
        | Update _ -> raise (RequestException "update") 
    

    は、あなたのコードとまったく同じ効果を達成します。

    +0

    +1、私はこの解決策が最も好きです。 – ildjarn

    関連する問題