如何引发打印消息并返回值的异常?

时间:2013-04-08 18:58:45

标签: exception-handling sml

我们的教授要求我们在作业中这样做:

  

如果给定的阈值为负,则应打印消息“错误:负阈值”并返回空列表。为此,定义一个名为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

所以我的代码只会在引发异常时返回一个空列表。鉴于异常必须具有与我们所知的函数相同的返回类型,我能做些什么才能返回空列表并打印错误消息?

2 个答案:

答案 0 :(得分:4)

正确的结果是,异常处理的结果类型必须与处理异常的表达式相同。换句话说,exp_1exp_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"; [])