异常
机制、目的以及思想和其他语言(如Java)中的异常几乎没有什么不同,所以我们重点关注异常在ML语言中的语法特性。
- 本质:ML语言中的内置类型
exn
(关于数据类型详见(四)数据类型) - 特性:1).
exn
类型的构造子集合可以通过声明语句被扩展
2).异常包不是ML的值,能识别它们的只有 r a i s e raise raise和 h a n d l e handle handle
声明
nullary exception
e x c e p t i o n exception exception E x Ex Ex,
其中exception
为ML关键字,Ex
为异常的名字(名字通常首字母大写)
///~eg:
exception Failure
相当于在内置类型exn
中扩展了一个名为
F
a
i
l
u
r
e
Failure
Failure的常量构造子,扩展操作也即声明语句,和数据类型中定义构造子的形式一样,这是自然的,因为异常本身就是ML的内置类型。同样依据构造子可看做构造函数特性,我们可以定义携带成员的异常值,
value-carrying exception
e x c e p t i o n exception exception E x Ex Ex o f of of t y p typ typ
///~eg:
exception Failedbecause of string;
exception Badvalues of int;
抛出异常
r
a
i
s
e
raise
raise
E
x
Ex
Ex
其中Ex
为异常e
或者值为exn类型
的表达式,作用就是计算出一个含值e的异常包
。
包含异常值的表达式的计算
三个原则
p1:计算过程是短路的(类似&&和||)
p2:函数遵循传值调用call-by-value
原则
p3:表达式遵循从左往右计算
- 含异常包的函数:
由p1和p2可知
f ( r a i s e f(raise f(raise E ) ⟺ r a i s e E)\iff raise E)⟺raise E E E
例如
r a s i e rasie rasie ( B a d v a l u e (Badvalue (Badvalue ( r a i s e (raise (raise F a i l u r e ) ) Failure)) Failure))
最后计算的值为Failure异常包 - 元组(
tuple
):
由p1和p3可知
( E 1 , E 2 , . . . , E n ) = E f (E_1,E_2,...,E_n)=E_f (E1,E2,...,En)=Ef
其中 E f = E_f= Ef= { E i , i = 1 , 2 , . . . , n ∣ E_i,i=1,2,...,n| Ei,i=1,2,...,n∣第一个值为异常的表达式} if-else
语句
i f if if E E E t h e n then then E 1 E_1 E1 e l s e else else E 2 E_2 E2
除了遵循p1,还应注意if-else
语句特殊性,如果 E E E为 t r u e true true,无论 E 2 E_2 E2为何值均不计算,同理如果 E E E为 f a l s e false false,则不计算 E 1 E_1 E1,如果 E E E的值为异常包,则整个if-else
表达式的值均为该异常包- 类似分析可知
let语句
和分情case表达式
中的计算情况
处理异常
书写类似case表达式
E
E
E
h
a
n
d
l
e
handle
handle
E
1
E_1
E1 =>
e
1
e_1
e1
(
∣
(|
(∣
E
2
E_2
E2 =>
e
2
e_2
e2
.
.
.
.
.
.....
.....
E
2
E_2
E2 =>
e
2
)
e_2)
e2)
如果没有匹配的异常,则将异常继续传递出去(也许能将它交给更外层的异常处理器处理)
注意异常处理器接收异常的作用域
-
if-else
语句
i f if if E E E t h e n then then E 1 E_1 E1 e l s e else else E 2 E_2 E2 h a n d l e ⋅ ⋅ ⋅ handle· · · handle⋅⋅⋅
这个 h a n d l e handle handle处理的是 E 2 E_2 E2
( i f (if (if E E E t h e n then then E 1 E_1 E1 e l s e else else E 2 ) E_2) E2) h a n d l e . . . handle... handle...
而这个 h a n d l e handle handle处理的是整个if-else
语句 -
case
表达式
c a s e case case E E E o f of of P 1 P_1 P1 => E 1 ∣ ⋅ ⋅ ∣ P n E_1 | · · | Pn E1∣⋅⋅∣Pn => E n E_n En h a n d l e ⋅ ⋅ ⋅ handle · · · handle⋅⋅⋅