F #: вложенные дискриминационные союзы и сопоставления - PullRequest
1 голос
/ 04 февраля 2012

У меня есть 2 вложенных различающихся объединения:

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).

В любом случае, по причине, которую я не понимаю, компилятор выдает мне 2 предупреждения:

  1. на Update(stype) Я получаю Это правило никогда не будетСовпадение
  2. на первом match stype Я получаю Неполные совпадения с образцом для этого выражения.Например, значение «Производители» может указывать на случай, не охватываемый шаблоном (ами).

Итак, вопрос в том, почему я получаю эти 2 предупреждения?Я что-то упустил из-за соответствия?

Ответы [ 3 ]

11 голосов
/ 04 февраля 2012

В то время как вложенные выражения соответствия иногда оправданы, в данном конкретном случае я бы написал более читаемое одноуровневое соответствие, если бы я был вами:

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")

, который достигает точно такого же эффекта, что и ваш код.

6 голосов
/ 04 февраля 2012

Ваша заключительная скобка не в том месте.

| 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.

2 голосов
/ 04 февраля 2012

Поскольку вы закрыли паратезы не в той точке, ваш код фактически становится:

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 with не покрывает Producers, а последний шаблон 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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...