奥卡姆介绍

发布于 2024-08-31 13:47:40 字数 561 浏览 4 评论 0原文

我现在正在尝试学习 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"]

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

此致 菲利普

i'm trying to learn ocaml right now and wanted to start with a little program, generating all bit-combinations:

["0","0","0"]
["0","0","1"]
["0","1","0"]

... and so on

My idea is the following code:

let rec bitstr length list =
  if length = 0 then
    list
  else begin
    bitstr (length-1)("0"::list);
    bitstr (length-1)("1"::list);
  end;;

But i get the following error:

Warning S: this expression should have type unit.
val bitstr : int -> string list -> string list = <fun>
# bitstr 3 [];;
- : string list = ["1"; "1"; "1"]

I did not understand what to change, can you help me?

Best regards
Philipp

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦晓ヶ微光ヅ倾城 2024-09-07 13:47:40

开始 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 情况返回 [list] 而不仅仅是 list 因此结果是列表的列表而不是平面列表。

begin foo; bar end executes foo and throws the result away, then it executes bar. Since this makes only sense if foo has side-effects and no meaningful return value ocaml emits a warning if foo has a return value other than unit, since everything else is likely to be a programmer error (i.e. the programmer does not actually intend for the result to be discarded) - as is the case here.

In this case it really does make no sense to calculate the list with "0" and then throw it away. Presumably you want to concatenate the two lists instead. You can do this using the @ operator:

let rec bitstr length list =
  if length = 0 then
    [list]
  else
    bitstr (length-1)("0"::list) @ bitstr (length-1)("1"::list);;

Note that I also made the length = 0 case return [list] instead of just list so the result is a list of lists instead of a flat list.

樱娆 2024-09-07 13:47: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的精神。

Although sepp2k's answer is spot on, I would like to add the following alternative (which doesn't match the signature you proposed, but actually does what you want) :

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);;

The first difference is that you do not need to pass an empty list to call the function bitsr 2 returns [["0"; "0"]; ["0"; "1"]; ["1"; "0"]; ["1"; "1"]]. Second, it returns a list of ordered binary values. But more importantly, in my opinion, it is closer to the spirit of ocaml.

清浅ˋ旧时光 2024-09-07 13:47:40

我喜欢获得其他想法!

所以这就是......

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

I like to get other ideas!

So here it is...

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

Result:

[["0"; "0"]; ["0"; "1"]; ["1"; "0"]; ["1"; "1"]]

[[0; 0]; [0; 1]; [1; 0]; [1; 1]]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文