Как я могу упростить вложенные предложения по сопоставлению шаблонов?

#pattern-matching #ocaml

#сопоставление с образцом #ocaml

Вопрос:

У меня есть вложенные типы данных с большим количеством option модификаторов. Я хочу упростить исходный код функций, когда мне нужны match вложенные типы.

Рассмотрим пример:

 type ty = Ty1 | Ty2

let func = function
  | Some v -> begin
    match v with
    | Ty1 -> Printf.printf "Ty1n"
    | Ty2 -> Printf.printf "Ty2n"
  end
  | None -> Printf.printf "Nonen"

let () =
  Printf.printf "n";
  let _ =  func @@ Some(Ty1) in ()
 

С большим количеством вложенных типов мой код становится очень огромным.

Вместо этого я хочу написать что-то вроде этого:

 let func = function
  | Some v when (v == Ty1) -> Printf.printf "Ty1n"
  | Some v when (v == Ty2) -> Printf.printf "Ty2n"
  | None -> Printf.printf "Nonen"
 

Каково наилучшее решение моей проблемы? Возможно ли это в синтаксисе OCaml?

Или, может быть, есть некоторые шаблоны проектирования, которые помогают мне избежать этой проблемы при разработке пользовательских типов данных?

Ответ №1:

Шаблоны также могут быть вложенными, поэтому вы можете просто сделать:

 let func = function
  | Some Ty1 -> Printf.printf "Ty1n"
  | Some Ty2 -> Printf.printf "Ty2n"
  | None -> Printf.printf "Nonen"
 

Ответ №2:

Вы могли бы избежать этого сопоставления вложенных шаблонов, определив две функции:

 type ty = Ty1 | Ty2

let ty_to_string = function
  | Ty1 -> "Ty1"
  | Ty2 -> "Ty2"

let func o = Option.fold ~none:"None" ~some:ty_to_string o |> Printf.printf "%sn"

let () =
  Printf.printf "n";
  let _ =  func @@ Some(Ty1) in ()
 

Мне кажется, что он более пригоден для повторного использования, поскольку в любом случае вам может понадобиться ty_to_string функция

Комментарии:

1. Спасибо! Option.fold выглядит очень круто. Это не подходит для моей текущей проблемы, но это хорошая функция.