Вложенные шаблоны OCaml - исключение, несмотря на определение шаблона - PullRequest
3 голосов
/ 20 января 2012

У меня есть функция, определенная так:

 let test_func lis =
   match lis with h::t ->
    match h with h2::t2 ->
      h2
    | [] ->
      []
  | [] ->
    [];;

При компиляции я получаю предупреждение о том, что эта функция не соответствует шаблону [] - даже если я определил ее как второй случай!Я обнаружил, что могу это исправить, окружив второе выражение соответствия паренами:

 let test_func lis =
   match lis with h::t ->
    (match h with h2::t2 ->
      h2
    | [] ->
      [])
  | [] ->
    [];;

, но мне было интересно, почему это необходимо.Кроме того, замена первого и второго регистра в выражении соответствия верхнего уровня также работает:

 let test_func lis =     
   match lis with [] ->
     []
   | h::t ->
    match h with h2::t2 ->
      h2
    | [] ->
      [];;

Спасибо!

1 Ответ

8 голосов
/ 20 января 2012

Если мы исправим отступ вашего кода, он будет выглядеть так:

let test_func lis =
  match lis with h::t ->
    match h with h2::t2 ->
      h2
    | [] ->
      []
    | [] ->
      [];;

Если вы посмотрите на это, станет очевидно, что нет разницы между первым и вторым | [] -> []. Таким образом, компилятор не может знать, что вы предполагали, что второй принадлежит внешнему оператору сопоставления, а не внутреннему. Таким образом, вам нужно заключить в скобки, чтобы сообщить компилятору, что внутренний оператор соответствия должен заканчиваться после первого | [] -> [].

Во второй версии первая | [] -> [] явно принадлежит внешнему оператору соответствия, потому что внутренний оператор поиска даже не появляется до тех пор, пока в программе не будет дальше. Таким образом, нет никакой двусмысленности и, следовательно, нет необходимости в скобках.

...