Nic*_*ume 1 f# pattern-matching discriminated-union
我有2个嵌套的歧视联盟:
type ServiceTypes =
| Contexts
| Context of int
| Producers
type ServiceActions =
| Get of ServiceTypes
| Update of ServiceTypes
Run Code Online (Sandbox Code Playgroud)
和嵌套的匹配语句:
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")))
Run Code Online (Sandbox Code Playgroud)
目标是使用看起来像这样的调用来构建请求字符串req.Send(Update Producers)
.
无论如何,由于我不理解的原因,编译器给了我2个警告:
Update(stype)
我得到一个这个规则永远不会匹配match stype
我得到一个不完整的模式匹配这个表达式.例如,值'Producers'可以指示模式未涵盖的情况.所以问题是为什么我会收到这两个警告?我是否错过了匹配工作的方式?
kkm*_*kkm 13
虽然嵌套匹配表达式有时是有保证的,但在这种特殊情况下,如果我是你,我会写一个更易读的单级匹配:
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")
Run Code Online (Sandbox Code Playgroud)
它实现了与您的代码完全相同的效果.
您的右括号位于错误的位置.
| Context(id) -> (sprintf "Context/%d" id))
| _ -> raise (RequestException("get"))
Run Code Online (Sandbox Code Playgroud)
应该
| Context(id) -> (sprintf "Context/%d" id)
| _ -> raise (RequestException("get")))
Run Code Online (Sandbox Code Playgroud)
实际上,为了清楚起见,我将摆脱所有无关的括号(在这种情况下实际上是每个括号):
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"
Run Code Online (Sandbox Code Playgroud)
就个人而言,我发现这更具可读性,但当然这是主观的,所以YMMV.