OCaml: использование `try` и` with` для больших программ - PullRequest
1 голос
/ 01 июня 2019

Предположим, у вас есть последовательность выражений, которые могут вызвать исключение.Если это произойдет, вы хотите, чтобы произошел какой-то долгий процесс.Если это не так, вы хотите, чтобы произошел другой длительный процесс.В императивных языках вы обычно можете сделать что-то вроде

try:
    ...
except:
    ...

, но я не могу воспроизвести это в OCaml, потому что кажется, что вы можете проверять только одно выражение за раз для исключения.Я также не понимаю, как вы можете использовать значение, если оно существует, или сделать что-то еще, если это не так.

Для более конкретного, если тривиальный пример: у меня есть функция list_max, которая возвращает максимум списка, если он не пустой, и вызывает исключение, если он пустой.Предположим, у меня есть список, и я хочу утверждать, что его максимум равен 4, но я ошибаюсь, и это действительно пустой список.Я не могу понять синтаксис правильно из объяснений, которые я нашел.Я попробовал следующее и много перестановок на нем:

try (list_max [])
with
| Failure s -> -1
| _ -> assert (list_max [] = 4);;

[Edit: скорее, чем надуманный пример выше, возможно, такой, который имеет больше смысла:функция.Я знаю, что могу сделать

assert ( (list_max [1;2;3] = 3 );;

Но как мне проверить, что list_max правильно выбрасывает исключение в пустой список?]

1 Ответ

3 голосов
/ 01 июня 2019

Вы можете сделать утверждение в выражении try, если оно вызывает исключение, которое вы не перехватываете. Любое другое исключение, такое как Assert_failure в этом случае, будет проходить через.

try assert (list_max [] = 4) with
| Failure s -> -1

Но assert возвращает unit, поэтому в любом случае это будет ошибка типа.

Альтернативой является использование исключительного случая при сопоставлении с образцом :

match list_max [] with
| exception (Failure _) -> -1
| _ -> assert (list_max [] = 4)

(здесь по-прежнему есть ошибка типа)

Наконец, вы можете захотеть использовать тип option или result вместо исключений, поскольку они намного безопаснее. Компилятор не позволит вам просто забыть об условиях ошибки. Если бы list_max вернул option, это будет:

match list_max [] with
| None -> -1
| Some _ -> assert (list_max [] = 4)

(все еще имеет ошибку типа)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...