Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
# type num = First of int | Second of float | Triple of int*int*int;;
type num = First of int | Second of float | Triple of int * int * int
# let multiply_by_five x =
match x with
First(a) -> First(a*5)
| Second(b) -> Second(b*.5.)
| Triple(a,b,c) -> Triple(a*5,b*5,c*5);;
val multiply_by_five : num -> num = # multiply_by_five (First 42);;
- : num = First 210
# multiply_by_five (Triple (1,2,3));;
- : num = Triple (5, 10, 15)
Иначе говоря, вы можете на основе существующих типов определить некий общий тип (что-то вроде union в С, только сложнее и умнее), с которым и работать дальше. Заметьте, обобщив разрешенные входные данные в какой-то единый тип, мы можем легко и изящно определять «а какой тип данных скормили функции».
# let sqr x =
match x with
First(a) -> First(a*a)
| Second(a) -> Second(a*.a)
| Triple(a,b,c) -> Triple(a*a,b*b,c*c);;
val sqr : num -> num = # sqr (First 5);;
- : num = First 25
# sqr (Triple (1,2,3));;
- : num = Triple (1, 4, 9)
Разница колоссальна, да.
А что касается «легко и изящно», тут надо понять две вещи. Чтобы вызвать операцию умножения (деления, прибавления 148) для какого-то аргумента, эта операция для данного типа должна быть определена. Если складывать штаны с табуретками, надо определить соответствующий оператор в любых языках. Просто в Си (бэйсик, пхп, ява, whatever) операторы и функции могут иметь одинаковые имена, вследствие чего выбор нужной функции и автоматическое приведение типа происходит автоматически на этапе компиляции. В чём-то это удобно, зачастую ещё и опасно. Окамл требует явного указания, какую функцию мы вызываем, взамен этого он позволяет нам выбирать поведение, в зависимости от типа, не только при вызове функции, но и абсолютно в любой момент. Более того, вышеупомянутым match можно, в зависимости от шаблонов, работать не только с типами, но и с конкретными значениями, содержимыми списков:
# let check_list x =
match x with
[] -> print_endline "list is empty"
| x :: [] -> print_endline "list has one element"
| x :: y :: [] -> print_endline "list has two elements"
| _ -> print_endline "too many";;
комментарии в OCaml очень похожи на комментарии в Си
Допустим, вы написали функцию, назовём её repeated, которая берёт исходную строку s, число n и возвращает новую строку, состоящую из троекратно повторённой строки s.
Введение в OCaml: The Basics [1]