SML问题:是否可以将异常作为函数中的参数传递?

时间:2018-09-24 03:17:19

标签: sml

我可以在sml函数中将异常作为参数传递吗?

如果是这样,会是这样吗?

int m = 1

2 个答案:

答案 0 :(得分:3)

是的,可以,但是类型是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

但是它是否对任何事情都有用是另一回事。

答案 1 :(得分:0)

是的,可以。类型为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内部处理此特定的Timeout异常,因为这是唯一允许对其进行模式匹配的地方。因此,如果f抛出了某些东西,那它就不会是超时(它可能是另一个称为“超时”的异常,该异常掩盖了该异常,或者完全是另一个异常)。

传递异常的另一种用例是,如果Standard ML支持与传下来的异常匹配的模式,但事实并非如此。如果您有一个传递的异常e,则handle e => ...会将e解释为变量异常,而不是将捕获的异常与变量中的异常统一。 las,您总是必须在可用的范围内静态地处理异常,无论如何这可能是一件好事。