SML问题:我可以在函数中作为参数传递异常吗?

SML问题:我可以在函数中作为参数传递异常吗?,sml,Sml,我可以在sml函数中作为参数传递异常吗 如果是这样,会是这样吗 foo(exc: exception) = ... 可以,但类型是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

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

如果是这样,会是这样吗

foo(exc: exception) =
    ...

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

但是它是否对任何东西有用是另一回事。

是的,你可以。类型为
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
并且要知道,这个特定的超时异常只能在
中使用
选项处理,因为这是唯一允许模式匹配的地方。因此,如果
f
抛出某个异常,则它不能是超时(它可以是另一个名为Timeout的异常,该异常将此异常隐藏起来,或者完全是另一个异常)


传递异常可能有用的另一个用例是,如果标准ML支持针对传递的异常进行模式匹配,但它不支持。如果有传递的异常
e
,则
handle e=>…
e
解释为变量异常,而不是将捕获的异常与变量中的异常统一起来。遗憾的是,您始终必须在异常可用的范围内静态处理异常,这可能是一件好事。

这对任何事情都有用,因为exn是SML的动态分类功能,这可能很有用