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
所以结果列表,而不是一个平面列表的列表。
虽然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的精神。
感谢您的回复。我喜欢得到其他想法! 因为我对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]]
啊我明白了,谢谢你的解释!你真的帮了我! – 2010-05-10 13:45:40