Вопрос SML: Могу ли я передать исключение в качестве параметра в функцию? - PullRequest
0 голосов
/ 24 сентября 2018

Могу ли я передать исключение в качестве параметра в функцию sml?

Если это так, будет ли это примерно так?

foo(exc: exception) =
    ...

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Да, вы можете.Тип 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 как исключение переменной, а не объединять перехваченное исключение с исключением из вашей переменной.Увы, вы всегда должны обрабатывать исключения статически в той области, в которой они доступны, что в любом случае, вероятно, хорошо.

0 голосов
/ 24 сентября 2018

Да, вы можете, но типом является exn, а не exception:

- exception E;
exception E
- E;
val it = E(-) : exn
- exception Q;
exception Q
- fun f x e = if x > 0 then x else raise e;
val f = fn : int -> exn -> int
- f 1 E;
val it = 1 : int
- (f 0 E) handle E => 23 | Q => 49;
val it = 23 : int
- (f 0 Q) handle E => 23 | Q => 49;
val it = 49 : int

Но полезно ли это для чего-либо, это другой вопрос.

...