jubnzv
jubnzv

Reputation: 1574

How can I simplify nested pattern matching clauses?

I have nested data types with a lot of option modifiers. I want to simplify the source code of functions when I need to match the nested types.

Consider example:

type ty = Ty1 | Ty2

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

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

With a large number of nested types, my code becomes very huge.

Instead, I want to write something like this:

let func = function
  | Some v when (v == Ty1) -> Printf.printf "Ty1\n"
  | Some v when (v == Ty2) -> Printf.printf "Ty2\n"
  | None -> Printf.printf "None\n"

What is the best solution for my problem? Is it possible in OCaml syntax?

Or may be there are some design patterns that help me avoid this problem when designing user-defined data types?

Upvotes: 1

Views: 175

Answers (2)

ghilesZ
ghilesZ

Reputation: 1586

You could avoid this nested pattern matching by defining two functions:

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 "%s\n"

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

It seems to me that it is more reusable as you might end up needing the ty_to_string function anyway

Upvotes: 1

glennsl
glennsl

Reputation: 29106

Patterns can be nested as well, so you can just do:

let func = function
  | Some Ty1 -> Printf.printf "Ty1\n"
  | Some Ty2 -> Printf.printf "Ty2\n"
  | None -> Printf.printf "None\n"

Upvotes: 3

Related Questions