每當我運行代碼時,disting true
和disting false
也變成了expression1。結果反之亦然此代碼與int和bool匹配的ocaml模式
let disting v =
match v with
| bool -> (*expression2*)
| int -> (*expression1*)
| _ -> (*expression3*)
這也有類似的問題。我怎樣才能得到我想要的結果?
每當我運行代碼時,disting true
和disting false
也變成了expression1。結果反之亦然此代碼與int和bool匹配的ocaml模式
let disting v =
match v with
| bool -> (*expression2*)
| int -> (*expression1*)
| _ -> (*expression3*)
這也有類似的問題。我怎樣才能得到我想要的結果?
模式匹配不像您認爲的那樣工作。
它可以讓你匹配值或像在以下值的方式表達:
match some_int with
| 1 -> 1
| 10 -> 2
| x -> x/2 (* this matches any possible int, and it gives it the name 'x' for the rest *)
所以在這裏你的意志,因爲它沒有任何的濾液的第一種情況總是匹配。你所說的是:用任何東西與v相匹配,在其餘部分我們稱它爲'bool'。
你便可以嘗試像
let disting v =
match v with
| true -> (*expression2*)
| 2 -> (*expression1*)
| _ -> (*expression3*)
不OCaml中進行類型檢查爲「V」或者是一個int或一個布爾值,但不能同時。 我不知道你想做什麼,但你應該讀一些關於語言的基礎。
做OCaml中的方法是使用和類型:
type i_or_b = I of int | B of bool;
let disting v =
match v with
| I x -> Printf.printf "v = I %d\n" x
| B x -> Printf.printf "v = B %s\n" (string_of_bool x)
TL;博士:寫兩個不同的功能,一個int和一個布爾值,並調用相應的一個根據上下文。
Pierre G.給出了一個很好的方法來實現你想要做的事情。儘管如此,我想補充一點,我相信你在函數編程中試圖完成的是根本錯誤;在運行類型中檢查類型是典型的命令式編程。這是爲什麼:
函數是一個地圖,需要從空間中的一些元素,並從另一個空間輸出的元素,這就是爲什麼在數學上,我們寫f: X -> Y
表示,一個功能是從太空X
的地圖空間Y
。特別是它的含義是f
只能將X
中的元素作爲輸入。如果X
是自然數的空格,那麼調用f(dog)
是沒有意義的。
我們所說的一切基本上都是在函數式編程中發生的,只是用類型替換空間,並且你得到一個函數是從一個類型到另一個類型的映射。這就是爲什麼我們使用諸如f :: int -> int
這樣的符號作爲我們的函數簽名,那麼它將不會很好地定義什麼f true
意味着什麼,因此您的程序將無法編譯,因爲它沒有任何意義。
因此,您可以再次使用Pierre的解決方案並定義一個實際上是int和bool聯合的類型(空間)。
type intOrBool = Int of int | Bool of bool;
然後定義intOrBool -> [output type]
類型的函數。但是再次理解它不同於可以接收int或者bool的函數,因爲intOrBool是一種全新的類型。
爲什麼以這種方式考慮問題非常重要?因爲函數式編程的強度正是這樣的:如果它沒有明確定義,它就不會編譯。在命令式語言中,你有一些函數可以接收某些類型,比如int,但是仍然可以接受任何東西。這可以使他們崩潰,或最糟糕的給予意想不到的行爲,可能導致混亂,咖啡濫用和security breaches。從更實際的角度來看,這實際上是我們剛纔解釋的理論的結果,OCaml在運行時不會跟蹤類型。類型檢查都是在編譯之前完成的,因爲一旦我們知道每件事都會被明確定義,那麼爲什麼我們會留意這些信息呢?在數學上,我們確信,錯誤類型不會發生錯誤。
總之,我個人對你的問題的回答是,你應該寫兩個不同的函數,一個取int和一個取bool並實現你想要的行爲。這具有可重用性的優點,對於大多數情況下想要完成的任務來說都是有益的,並且最終更接近於通常在函數編程中使用的策略,這種編程是編寫並編寫小型構建塊功能。