我试图学习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;;
但是我收到以下错误:
Warning S: this expression should have type unit. val bitstr : int -> string list -> string list =# bitstr 3 [];; - : string list = ["1"; "1"; "1"]
我不明白要改变什么,你能帮助我吗?
最好的问候Philipp
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);;
请注意,我还使用length = 0
case返回[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的精神.