Ocaml介绍

问题描述:

我想学习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"] 

我不明白要改变什么,你能帮助我吗?

问候 菲利普

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

虽然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

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]]