我试图学习ocaml的现在,想入手一个小程序,生成所有位组合:"0","0","0"] ["0","0","1"] ["0","1","0"] ......依此类推
我的想法是以下代码:
let rec bitstr length list =
if length = 0 then
list
else begin
bitstr (length-1)("0"::list);
bitstr (length-1)("1"::list);
end;;
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
Warning S: this expression should have type unit.
val bitstr : int -> string list -> string list = <fun>
# bitstr 3 [];;
- : string list = ["1"; "1"; "1"]
Run Code Online (Sandbox Code Playgroud)
我不明白要改变什么,你能帮助我吗?
最好的问候Philipp
sep*_*p2k 14
begin foo; bar end执行foo并抛出结果,然后执行bar.因为只有foo副作用并且没有有意义的返回值才会有意义,如果foo具有除unit之外的返回值,则ocaml会发出警告,因为其他所有内容都可能是程序员错误(即程序员实际上并不打算使用结果被丢弃) - 就像这里的情况一样.
在这种情况下,用"0"计算列表并将其扔掉是没有意义的.大概你想要连接两个列表.您可以使用@运算符执行此操作:
let rec bitstr length list =
if length = 0 then
[list]
else
bitstr (length-1)("0"::list) @ bitstr (length-1)("1"::list);;
Run Code Online (Sandbox Code Playgroud)
请注意,我还使用length = 0case返回[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);;
Run Code Online (Sandbox Code Playgroud)
第一个区别是你不需要传递一个空列表来调用函数bitsr 2返回[["0"; "0"]; ["0"; "1"]; ["1"; "0"]; ["1"; "1"]].其次,它返回有序二进制值的列表.但更重要的是,在我看来,它更接近于ocaml的精神.