options 類型不是很好理解铅协,我寫下 coursera 上的講解、例子和自己的理解壳炎,來幫助自己和看到這篇的你們來梳理想法僚焦。
Example
fun old_max (xs : int list) =
if null xs
then 0
else if null (tl xs)
then hd xs
else
let val tl_ans = old_max(tl xs)
in
if hd xs > tl_ans
then hd xs
else tl_ans
end
使用 options 類型的動(dòng)機(jī)
讓 max 函數(shù)在 list 空時(shí)返回 0 這種處理方式很糟
- 可以拋出一個(gè)異常
- 可以返回一個(gè)包含 0 個(gè)元素或 1 個(gè)元素的 list
- 這種方式可行但不好,因?yàn)榉祷乜者@種情況很常見谚攒,而且針對這種情況阳准,已經(jīng)設(shè)計(jì)了專門的 options 來處理
Options
- 對于任意的 t 類型,t option 都是一種類型
- (很像 t list馏臭,但是區(qū)別于 list野蝇,是一種不同的類型)
創(chuàng)建:
- NONE 類型為 'a option (類似于 [] 的類型 'a list)
- SOME 如果 e 的類型為 t,那么 e 就擁有類型 t option (類似 e :: [])
訪問:
- isSome 'a option -> bool括儒,如果值為 SOME绕沈,返回 true,如果為 NONE帮寻,返回 false
- valOf 'a option -> 'a七冲,從 option 類型中取值,如果給出 NONE 則拋出異常
注:個(gè)人感覺跟 java 的泛型有點(diǎn)像规婆。
A Better Implementation
(* better: returns an int option *)
(* fn : int list -> int option *)
fun max1 (xs : int list) =
if null xs
then NONE
else
let val tl_ans = max1(tl xs)
in if isSome tl_ans andalso valOf tl_ans > hd xs
then tl_ans
else SOME (hd xs)
end
- andalso 在這里類似 java 中的 &&,條件與蝉稳;類似的 orelse 表示或抒蚜。
- 這種方式雖然不錯(cuò),但每次都要使用 isSome 檢查類型是否為 NONE耘戚,每次都要使用 valOf 取值嗡髓。
A Little Bit Better Implementation
(* looks the same as max1 to clients
implementation avoids valOf *)
fun max2 (xs : int list) =
if null xs
then NONE
else let
fun max_nonempty (xs : int list) =
if null (tl xs)
then hd xs
else let val tl_ans = max_nonempty(tl xs)
in
if hd xs > tl_ans
then hd xs
else tl_ans
end
in
SOME (max_nonempty xs)
end
小結(jié):任意的類型都可以包裝成對應(yīng)的 Option。NONE 是一種 Option收津,如果把整數(shù) 3 包裝成 Option饿这,則是 SOME 3浊伙,SOME e 表示把表達(dá)式 e 包裝成 Option 類型,isSome t 表示查看 t 的類型是否為 Option长捧,而 valOf 則是取出 Option 類型中的值嚣鄙,比如 valOf(SOME 3) 為 3。