我们的教授要求我们在作业中这样做:
如果给定的阈值为负,则应打印消息“错误:负阈值”并返回空列表。为此,定义一个名为ThresholdOutOfRange的异常,如果阈值为负则引发异常,并处理异常以实现正确的行为。
我不明白如何引发异常,返回值并打印错误消息。现在我提出异常的代码是(只有重要的位除外):
fun getnearbylist(center, threshold, ziplist) =
let
exception ThresholdOutOfRange;
fun test_threshold(threshold, zip, nil) =nil
| test_threshold(threshold, zip, ziplist as x::xs) =
if (threshold <0.0) then raise ThresholdOutOfRange
(* [...skipped a long unrelated middle bit. most important is just knowing
this function returns a string list...] *)
else x::test_threshold(threshold, zip, xs)
in
test_threshold(threshold, center, ziplist)
handle
ThresholdOutOfRange => []
end
所以我的代码只会在引发异常时返回一个空列表。鉴于异常必须具有与我们所知的函数相同的返回类型,我能做些什么才能返回空列表并打印错误消息?
答案 0 :(得分:4)
正确的结果是,异常处理的结果类型必须与处理异常的表达式相同。换句话说,exp_1
和exp_2
必须具有相同的类型。在代码下面,就像if-expression的“then”和“else”部分一样。
exp_1 handle pat => exp_2
所以你要找的是一种在exp_2
部分做多件事的方法,特别是那些具有打印信息副作用的东西。对于这样的事情,你可以使用序列。序列具有以下形式(注意括号)
(exp_1; ... ; exp_n)
本身就是一个表达。这将在以下
中进行说明- (print "foo\n"; print "bar\n"; 42);
foo
bar
val it = 42 : int
从中我们可以看到序列的最终结果是exp_n
评估的结果。
由于序列经常在let-expression中使用,因此允许编写以下内容(没有前面提到的括号)
let dec in exp_1 ; ... ; exp_n end
奖励信息
序列实际上是一系列案例的派生形式(句法糖)。以下
(expr_1 ; ... ; exp_n ; exp)
相当于
case expr_1 of _ =>
case ... =>
case exp_n of _ => exp
答案 1 :(得分:1)
首先,声明例外:
exception OutOfRangeException;
定义将引发异常的函数:
fun someFunc x = if x < 0 then raise OutOfRangeException else [1,2,3,4] (*return some list*)
最后,通过打印消息并返回来处理异常的函数 和空列表:
fun someFunc_test x= (someFunc x) handle OutOfRangeException => (print "exception"; [])