Да, вы можете.Тип exn
.Вот пример того, где это может быть полезно:
Скажем, у вас есть функция, которую вы не знаете, завершается она или нет, и вы хотите справиться с этим, заключив ее в функцию, которая порождает потоквызывает функцию в потоке, устанавливает время ожидания и, если функция не вернулась в течение времени ожидания, убивает поток и генерирует исключение времени ожидания, переданное в качестве аргумента.
Псевдокод может выглядеть следующим образом:
fun with_timeout t e f =
let val f' = ...run f inside thread...
...wait t time for thread to join...
...otherwise, kill thread and raise e...
in f' end
Эта функция будет иметь тип time -> exn -> ('a -> 'b) -> ('a -> 'b)
.
Затем вы можете написать
fun with_timeout_option t f =
let exception Timeout
in SOME (with_timeout t Timeout f)
handle Timeout => NONE
end
и знать, что это конкретное исключение Тайм-аута может быть обработано только внутри with_timeout_option
, потому что это единственное место, где разрешено сопоставление с образцом.Поэтому, если f
что-то выбрасывает, это не может быть Timeout (это может быть другое исключение, называемое Timeout, которое затеняет это, или другое исключение целиком).
Другой вариант использования, где может быть полезной передача исключенийбыло бы, если бы Standard ML поддерживал сопоставление с шаблоном по исключению, которое было передано, но это не такЕсли у вас есть переданное исключение e
, handle e => ...
будет интерпретировать e
как исключение переменной, а не объединять перехваченное исключение с исключением из вашей переменной.Увы, вы всегда должны обрабатывать исключения статически в той области, в которой они доступны, что в любом случае, вероятно, хорошо.