Обработка ошибок
Ахтунг
Этот раздел находится в неопределённом состоянии.
Монады vs исключения
Всё зависит от вашего стиля написания кода.
Когда и что использовать
Используйте исключения для фатальных ошибок, либо ошибок, которые зачастую не произойдут. Монады для ожидаемых ошибок, ошибок бизнес-логики, вроде некорректных данных от пользователя и т.д..
Двойники
Иногда для удобства делают функции-двойники (с суффиксом _exn
), которые выкидывают исключение в случае ошибки.
Мем
Монады
Преимущества
- Кодируются в сигнатуре функции (про них сложно "забыть")
- Требуют явной обработки, либо использования монадики
Монадика
Про монады можно почитать в 8.7. Monads.
Операторы
Смотрите Binding operators.
Операторы | Функция | Описание |
---|---|---|
>>= , let* | bind | Монадическое связывание, определяющие монадическую последовательность |
>>| , >|= let+ | map | Отображение (между двумя категориями) |
Историческая справка
Начиная с версии 4.08 появилась возможность определять let-in
конструкцию.
Пример
let (let+) o f = Option.map f o
let (and+) ao bo = Option.bind ao (fun a -> let+ b = bo in a, b)
let map2 f xo yo =
let+ x = xo
and+ y = yo in
f x y
(* - ('a -> 'b -> 'c) -> 'a option -> 'b option -> 'c option = <fun> *)
ppx
Для некоторых библиотек, вроде lwt
, делают ppx-расширения.
Пример
let%lwt users = get_users_from_db ()
(* Lwt.bind (get_users_from_db ()) @@ fun users -> ... *)
Исключения
Перехват исключений
Помимо обычной конструкции try ... with
для перехвата возникших исключений, их можно ловаить внутри match
выражения:
let try_hd xs =
match List.hd xs with
| x -> Some x
| exception Failure "hd" -> None