Ocaml介绍

时间:2010-05-10 13:22:10

标签: ocaml

我正在尝试学习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 = <fun>
# bitstr 3 [];;
- : string list = ["1"; "1"; "1"]

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

祝你好运 菲利普

3 个答案:

答案 0 :(得分:14)

begin foo; bar end执行foo并抛出结果,然后执行bar。因为只有当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,因此结果是列表而不是平面列表。

答案 1 :(得分: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的精神。

答案 2 :(得分:0)

  

我想得到其他想法!

所以这就是......

bash

<强>结果:

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