首页 > 解决方案 > 如何在ocaml中使用python中的“i for i in”构造

问题描述

我有一个python函数:

def foo(n, d = 0):
    if n == 0:return [[]]
    print(x for x in foo(n-1, 0))
    return [[0] + x for x in foo(n-1, 0)] + [[1] + x for x in foo(n-1, 1)]

在 ocaml 它应该看起来像

let foo ?(d=0) n =
    if n = 0 then [[]]
    else [[0] @ foo (n-1)] @ [[1] @ foo (n-1) ~d:1]

但我有一个错误:

Error: This expression has type int list list
       but an expression was expected of type int list
       Type int list is not compatible with type int

我认为我对“x for x in foo(n-1, 0)”做错了,但我不明白如何解决它(也许 List.iter 可能会有所帮助,但我知道怎么做)

标签: pythonocaml

解决方案


这个 Python 片段:

[0] + x for x in foo(n-1, 0)

解析如下:

([0] + x) for x in foo(n-1, 0)

不是这样的:

[0] + (x for x in foo(n-1, 0))

换句话说,您要添加0到每个生成的列表的前面。在 OCaml 中执行此操作的方法是List.map

List.map (fun x -> 0 :: x) (foo (n - 1))

OCaml 没有列表推导,所以你不应该复制 Python 中的括号[x for x in ... ]

由于foo想要递归调用自身,因此您需要将其声明为递归函数let rec

如果您进行这三个更改,您将得到:

let rec foo ?(d=0) n =
    if n = 0 then [[]]
    else
        List.map (fun x -> 0 :: x) (foo (n-1)) @
        List.map (fun x -> 1 :: x) (foo (n-1) ~d: 1)

此代码的更紧凑形式是这样的:

let rec foo n =
  if n = 0 then [[]]
  else let m = foo (n - 1) in List.(map (cons 0) m @ map (cons 1) m)

作为旁注,您的两个函数都没有使用名为d. 这大概是因为它们已经从更复杂的代码中删减了。


推荐阅读