等同于 OCaml 中 haskell 的 zipwith

Equivalent of haskell's zipwith in OCaml

我有一个 'a 和一个 'b 的列表,以及一个 'a -> 'b-> 'c 类型的函数。我正在尝试将该函数应用于 a-list 的每个元素,其中 b 我已经有了,并制作了一个 'c' 列表。在 haskell 中,我会做类似 zipWith(foobar) a-list (replicate (length a) b). 的事情 在 OCaml 中执行此操作的等效方法是什么?

"List.map2" 相当于 Haskell 的 "zipWith"

val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list

好吧,在你的例子中你并不需要 zipWith,你可以使用一个简单的 map:

List.map (fun a -> f a b) a_list

这将比 List.map2(相当于 zipWith)更有效,因为 OCaml 处理列表的方式与 Haskell 不同,因此构建一个虚拟列表只是为了为了迭代,真的不值得。

OCaml 中的等价物是:

 open Core_kernel.Std

 let replicate n b = List.init n ~f:(fun _ -> b)
 List.(map2_exn a (replicate (length b) b) ~f:your_function)

不过,此代码出现的问题很少。比如,您确定要将列表作为函数的第二个参数吗?而且,为什么要复制第二个参数,而不是像@PatJ 所建议的那样将其作为自由变量传递给您的函数。这不仅仅是关于懒惰与急切的评估。在Haskell中还是需要遍历list,b会遍历两次。计算是惰性的这一事实并不意味着它在评估时会更快。

但是,OCaml 的核心库仍然提供了一个名为 Sequence 的惰性列表,其行为类似于 Haskell 的行为。代码将是相同的,模模块名称,即,只需将 List 替换为 Sequence.