Ошибка: переменная ... должна происходить с обеих сторон этого |шаблон - PullRequest
2 голосов
/ 27 ноября 2011

Я хочу написать сопоставление с шаблоном следующим образом:

match ... with
...
| Const1 (r, c) | Const2 (m, n) 
  -> expr

Возвращает ошибку: Error: Variable c must occur on both sides of this | pattern.

Нужно ли писать expr дважды (один раздля Const1, в другое время для Const2)?Может ли кто-нибудь помочь?

Ответы [ 2 ]

5 голосов
/ 27 ноября 2011

Как говорится в сообщении об ошибке, шаблон Or (| pattern) требует привязки к тому же набору переменных. Поэтому:

match ... with
...
| Const1 (m, n) | Const2 (m, n) 
  -> expr

или

match ... with
...
| Const1 (m, n) | Const2 (n, m) 
  -> expr

будет работать.

Конечно, вы можете сделать это, только если Const1 и Const2 принимают один и тот же тип. В некоторых случаях вы все равно делаете это, если у вас есть части конструкций одного типа:

match ... with
...
| Const1 (m, _) | Const2 (_, m) 
  -> expr

Подводный камень паттерна Or заключается в том, что вы не знаете, в каком конструкторе вы находитесь. Поэтому, если логика expr зависит от Const1 или Const2, вы больше не сможете использовать паттерн Or.

0 голосов
/ 20 апреля 2014

В качестве примера того, почему это может быть проблемой, рассмотрим, что произойдет, если expr зависит от r или c, а соответствующий объект соответствует типу Const2:

let c2 = Const2(1,2) in
match c2 with
...
| Const1 (r,c) | Const2 (m,n) -> r + 1

Поскольку c2 относится к типу Const2, r не определен справа от ->, поэтому OCaml не знает, как вычислять r+1.Компилятор ловит, что это произойдет, и заставляет вас изменить свой код, чтобы избежать этого.

Я предполагаю, что expr не зависит от того, имеет ли тип ввода Const1 или Const2 (в противном случае вы бы поместили эти случаи в отдельные строки с разными выражениями), так что вы можете обойтись без

match ... with
...
| Const1 _ | Const2 _ -> expr

Если вам нужно сопоставить в каком-то поле, что Const1 и Const2 обаесть, см. ответ пэда.

...