2010-05-10 223 views
5

我想學習ocaml現在想要開始一個小程序,生成所有位組合: [「0」,「0」,「0」] [「0」,「 0" , 「1」] [ 「0」, 「1」, 「0」] ......等等Ocaml介紹

我的想法是下面的代碼:

let rec bitstr length list = 
    if length = 0 then 
    list 
    else begin 
    bitstr (length-1)("0"::list); 
    bitstr (length-1)("1"::list); 
    end;; 

,但我得到的以下錯誤:

Warning S: this expression should have type unit. 
val bitstr : int -> string list -> string list = <fun> 
# bitstr 3 [];; 
- : string list = ["1"; "1"; "1"] 

我不明白要改變什麼,你能幫助我嗎?

問候 菲利普

回答

14

begin foo; bar end執行foo和拋出的結果了,那麼它執行吧。因爲這隻有在foo有副作用並且沒有有意義的返回值時纔有意義,如果foo具有非單位返回值,ocaml會發出警告,因爲其他一切都可能是程序員錯誤(即程序員實際上並不打算結果將被丟棄) - 這裏就是這種情況。

在這種情況下,用「0」計算列表然後丟棄它確實沒有意義。大概你想連接兩個列表。您可以使用@運營商做到這一點:

let rec bitstr length list = 
    if length = 0 then 
    [list] 
    else 
    bitstr (length-1)("0"::list) @ bitstr (length-1)("1"::list);; 

請注意,我也做了length = 0情況下返回[list],而不是僅僅list所以結果列表,而不是一個平面列表的列表。

+0

啊我明白了,謝謝你的解釋!你真的幫了我! – 2010-05-10 13:45:40

5

雖然sepp2k的答案是當場上,我想補充以下備選(不你提出的簽名匹配,但實際上你想要做什麼):

let rec bitstr = function 
    0 -> [[]] 
| n -> let f e = List.map (fun x -> e :: x) and l = bitstr (n-1) in 
     (f "0" l)@(f "1" l);; 

第一個區別是,您不需要傳遞空列表來調用函數bitsr 2返回[["0"; "0"]; ["0"; "1"]; ["1"; "0"]; ["1"; "1"]]。其次,它返回一個有序的二進制值列表。但更重要的是,在我看來,它更接近ocaml的精神。

+0

感謝您的回覆。我喜歡得到其他想法! 因爲我對Ocaml不熟悉,所以這個解決方案更難以理解。我會在幾天內給它一個機會;) – 2010-05-11 17:16:50

0

I like to get other ideas!

所以這裏...

let rec gen_x acc e1 e2 n = match n with 
| 0 -> acc 
| n -> (
    let l = List.map (fun x -> e1 :: x) acc in 
    let r = List.map (fun x -> e2 :: x) acc in 
    gen_x (l @ r) e1 e2 (n - 1) 
);; 

let rec gen_string = gen_x [[]] "0" "1" 
let rec gen_int = gen_x [[]] 0 1 

gen_string 2 
gen_int 2 

結果:

[["0"; "0"]; ["0"; "1"]; ["1"; "0"]; ["1"; "1"]] 

[[0; 0]; [0; 1]; [1; 0]; [1; 1]]