2012-09-05 41 views
10

我是OCaml的新手,我試圖理解你應該如何從'一個選項中獲得價值。根據http://ocaml-lib.sourceforge.net/doc/Option.html的文檔,有一個類型爲'a option - >'的get函數,它可以做我想要的。但是當我輸入:OCaml Option得到

# let z = Some 3;; 
val z : int option = Some 3 
# get z;; 
Error: Unbound value get 
# Option.get z;; 
Error: Unbound module Option 

爲什麼不能正常工作?

+3

您正在查看OCaml的可選實用程序庫ocaml-lib的文檔。當然,你不需要該庫來訪問'Some'構造函數中的值。 –

回答

14

獲取OCaml中任何一種構造函數內部值的傳統方法是模式匹配。模式匹配是OCaml的一部分,它可能與您在其他語言中已經看到的最爲不同,所以我建議您不要像您習慣的那樣編寫程序(例如繞過ocaml-lib的問題),而是嘗試一下,看看你是否喜歡它。

let contents = 
    match z with 
    Some c -> c;; 

可變contents分配3,但你得到一個警告:

警告8:這個模式匹配並不詳盡。這裏是不匹配的值的例子 :無

在一般情況下,你不會知道,你想看看裏面的表現必然是一個Some c。選擇選項類型的原因通常是有時該值可以是None。這裏編譯器提醒你,你沒有處理可能的情況之一。

您可以進行模式匹配「深入」,編譯器仍然會檢查窮盡性。考慮這個函數,它的(int option) option

let f x = 
    match x with 
    Some (Some c) -> c 
    | None -> 0 
    ;; 

在這裏,你忘了的情況下Some (None),編譯器會告訴你這麼:

警告8:這個模式匹配並不詳盡。下面是一個示例 的值不匹配:某些無無

+4

值得一提的是,你的第一個例子相當於'讓一些c = z在c' –

+0

在這個答案中,我專門使用'match with'進行模式匹配,因爲後者是手頭的主題,我不認爲它首先傷害到它與一個單一的構造。 –

+0

我同意你的看法,這就是爲什麼我添加這個factoid作爲評論;) –

9

通常的做法是使用模式匹配。

# let x = Some 4;; 
val x : int option = Some 4 

# match x with 
    | None -> Printf.printf "saw nothing at all\n" 
    | Some v -> Printf.printf "saw %d\n" v;; 
saw 4 
- : unit =() 

您可以編寫自己的get函數(雖然你必須決定 你想做的事,如果值是無什麼)。

+0

這是一個很好的答案。爲了擴展這個例子,我們讓x保持一個字符串並打印: https://gist.github.com/shehaaz/7165109 因此,您可以編寫一個處理所有類型的通用函數。 – Shehaaz

4

你應該聽聽上述海報有關類型安全的建議,但也要注意,諸如Option.get之類的不安全功能(可在電池中使用btw)通常後綴爲exn。如果您好奇這是如何實現Option.get或Option.get_exn,那麼:

let get_exn = function 
    | Some x -> x 
    | None -> raise (Invalid_argument "Option.get")