Skip to content

Обработка ошибок

Монады vs исключения

Всё зависит от вашего стиля написания кода.

Когда и что использовать

Используйте исключения для фатальных ошибок, либо ошибок, которые зачастую не произойдут. Монады для ожидаемых ошибок, ошибок бизнес-логики, вроде некорректных данных от пользователя и т.д..

Двойники

Иногда для удобства делают функции-двойники (с суффиксом _exn), которые выкидывают исключение в случае ошибки.

Мем

Монады

Преимущества

  • Кодируются в сигнатуре функции (про них сложно "забыть")
  • Требуют явной обработки, либо использования монадики

Монадика

Про монады можно почитать в 8.7. Monads.

Операторы

Смотрите Binding operators.

ОператорыФункцияОписание
>>=, let*bindМонадическое связывание, определяющие монадическую последовательность
>>|, >|= let+mapОтображение (между двумя категориями)

Историческая справка

Начиная с версии 4.08 появилась возможность определять let-in конструкцию.

Пример

ocaml
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-расширения.

Пример

ocaml
let%lwt users = get_users_from_db ()
(* Lwt.bind (get_users_from_db ()) @@ fun users -> ... *)

Исключения

Перехват исключений

Помимо обычной конструкции try ... with для перехвата возникших исключений, их можно ловаить внутри match выражения:

ocaml
let try_hd xs = 
    match List.hd xs with 
    | x -> Some x
    | exception Failure "hd" -> None