Подходим любой конструктор - PullRequest
0 голосов
/ 28 сентября 2019

Учитывая этот тип:

type typeT =
  | A of int
  | B of int
  | C of int
  | D of int

Я хочу упростить следующее совпадение (возвращая значение по умолчанию при сопоставлении D и идентичность в противном случае):

let match_example_1 t =
  match t with
  | A x -> A x 
  | B x -> B x 
  | C x -> C x 
  | D x -> D 1 
  ;;

Во что-то вместестроки этого:

let match_example_2 t = 
  match t with
  | D x -> D 1 
  | f x -> f x
  ;;

Или вот это:

let match_example_3 t = 
  match t with
  | f x when f == D -> f 1
  | f x -> f x
  ;;

Но я получаю синтаксическую ошибку при сопоставлении f x.Я предполагаю, что есть кое-что о том, какие конструкторы на самом деле есть в ocaml и как выполняется сопоставление с образцом, что я не понимаю.Хотя мне не удалось найти причину, надеюсь, кто-то здесь может помочь.

Ответы [ 3 ]

0 голосов
/ 28 сентября 2019

Вы также можете просто вернуть исходное значение, если оно не соответствует тому, что вы ищете:

match t with
| D _ -> D 1
| _   -> t

То, что вы предлагаете, будет полезно, только если вы хотите манипулировать содержащимся значением, например f x -> f (x + 1), но вопросы, которые я задал в комментарии выше, все еще применяются.Что делать, если есть конструктор, который не следует точно такой же форме?Что бы вы ожидали, если бы вы добавили E of string или F of int * string к typeT?

0 голосов
/ 29 сентября 2019

Вы можете использовать ярлык _, но вы потеряете преимущество функции проверки исчерпанности

Вы также можете использовать что-то вроде

    match t with
    A x | B x | C x -> f x
    D x -> t 

Таким образом, если в будущем форма вашегоПри изменении структуры данных проверка типов поможет вам в процессе рефакторинга благодаря исчерпывающей проверке.

0 голосов
/ 28 сентября 2019

Вы не можете делать то, что вы хотите напрямую.Вы можете немного разложить на множители, сопоставив несколько вещей вместе.

match t with
| A x
| B x
| C x -> x 
| D x -> 1 

Это, однако, не позволит вам получить A, B или C.

Однако вы можете сделать что-то более близкое, если вы хранили свои данные по-другому.

type kind = A | B | C | D

type t = kind * int

А затем выполните

match t with
| (D, x) -> (D, 1)
| (f, x) -> (f, x)
...