Когда вы пишете выражение соответствия шаблону, вы не можете использовать произвольные функции в своих шаблонах.Вы можете использовать только конструкторы , которые выглядят как неоцененные функции.Например, функция «+» определена на целых числах.Таким образом, выражение 1+2
оценивается и дает 3;функция "+" оценивается, поэтому вы не можете найти совпадения на x+y
.Вот попытка определить функцию для натуральных чисел, которая проверяет, является ли число нулевым:
let f x = match x with
| 0 -> false
| a+1 -> true
;;
Это не может работать!По той же причине ваш пример со строками не может работать.Функция "^" вычисляется на строках, она не является конструктором.
Соответствие на x+1
будет работать только в том случае, если числа были бы неоцененными символьными выражениями, сделанными из неоцененного оператора +
и символической константы1
.Это не так в OCAML.Целые числа реализуются непосредственно через машинные номера.
Когда вы сопоставляете тип варианта, вы сопоставляете конструкторы, которые являются оцененными выражениями.Например:
# let f x = match x with
| Some x -> x+1
| None -> 0
;;
val f : int option -> int = <fun>
Это работает, потому что тип 'a option
состоит из символического выражения, такого как Some x
.Здесь Some
- это не функция, которая оценивается и дает какое-то другое значение, а скорее «конструктор», который можно рассматривать как функцию, которая никогда не оценивается.Выражение Some 3
больше не оценивается;осталось как есть.Только для таких функций вы можете сопоставлять с образцом.
Списки также являются символическими, неоцененными выражениями, построенными из конструкторов;Конструктор ::
.Результат x :: y :: []
является неоцененным выражением, которое представлено списком [x;y]
только для косметического удобства.По этой причине вы можете сопоставлять шаблоны в списках.