Reputation: 8434
I have 2 nested discriminated unions:
type ServiceTypes =
| Contexts
| Context of int
| Producers
type ServiceActions =
| Get of ServiceTypes
| Update of ServiceTypes
And a nested match statement:
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")))
The goal is to build a request string with a call looking like that req.Send(Update Producers)
.
Anyway for a reason that I do not understand, the compiler gives me 2 warnings:
Update(stype)
I get a This rule will never be matchedmatch stype
I get a Incomplete pattern matches on this expression. For example, the value 'Producers' may indicate a case not covered by the pattern(s).So the question is why do I get these 2 warnings? Did I miss something on the way matching works?
Upvotes: 2
Views: 2351
Reputation: 62975
Your closing parenthesis is in the wrong place.
| Context(id) -> (sprintf "Context/%d" id))
| _ -> raise (RequestException("get"))
should be
| Context(id) -> (sprintf "Context/%d" id)
| _ -> raise (RequestException("get")))
Indeed, for the sake of clarity I would get rid of all extraneous parentheses (which in this case is actually every parenthesis):
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"
Personally I find this more readable, but of course that's subjective so YMMV.
Upvotes: 6
Reputation: 41290
Since you closed the paratheses in the wrong point, your code actually becomes:
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")))
Obviously you can see the first match stype with
doesn't cover Producers
and the last pattern Update(stype)
never matches due to the previous pattern of _
. Therefore, all compiler warnings are justified.
You seem to overuse paratheses; here is a cleaned up version:
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"
Upvotes: 2
Reputation: 5510
While nested match expressions are sometimes warranted, in this particular case I would write a more readable single-level match, if I were you:
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")
which achieves exactly the same effect as your code.
Upvotes: 17