在 OCaml 中扩展 int 数组功能

Extending int array functionality in OCaml

我不太确定如何搜索这个问题。

假设我在 int array 上使用了一堆函数,例如按分量减去其中的两个(如果它们具有相同的长度)等等。有没有一种惯用的方法来处理这个问题?我应该如何将 ints(或其他类型)上的操作提升为 int arrays(或其他类型的数组)上的操作?我应该使用仿函数还是采用其他方法?

编辑:我希望能够将 ints 或 floats 等数字类型的算术运算提升到相应数组上的算术运算。我还是应该只写函数吗?

写函数就好了。无需使用仿函数或其他任何东西,只需保持简单明了即可。可读性应该是首要任务。

如果你想让你的函数在数组模块中,你可以使用以下技巧:

module Array = struct 
  include Array
  let diff xs ys = ys
end

现在您有了一个模块 Array,其中包含所有现有功能以及您的功能。当然,这不会改变真正的 Array 模块,只会在词法范围内起作用。

更新

如果您的算法足够通用,仅依赖于某些特定的代数,那么您可以使用模块类型抽象该代数,并使用函子或 first-class 模块通过该代数参数化您的代码。一个很好的例子是 sum function in Container interface. It is parametrized with a first class module (a module packed into a value), that must implement commutative group 代数(求和函数所必需的)。基本上,用法是这样的:

 List.sum (module Int) ~f:ident [1;2;3;4]

 Array.sum (module Int) ~f:ident [| 1;2;3;4|]

此外,此代码稍后可以轻松重写以采用新的 modular implicits,它将在下一版本的 OCaml 中可用。

您有这些 'Iterators on two lists' 列表。 我想它们足以满足您的需求。

我想您可以改用列表(或者将您的数组转换为列表并再次将它们转换回来,但这听起来不必要地昂贵),或者简单地自己编写这些函数。

这是一个例子:

let array_map2 f a a' =
  let n = Array.length a in
  assert (n = Array.length a');
  if n = 0 then [||]
  else begin
    let r = Array.make n (f a.(0) a'.(0)) in
    for i = 0 to n - 1 do
      r.(i) <- f a.(i) a'.(i)
    done ;
    r
  end

array_map2 : ('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array

此函数的工作原理(假设它有效)如下:

array_map2 f [| a1 ; a2 ; ... ; an |] [| b1 ; b2 ; ... ; bn |] = [| f a1 b1 ; f a2 b2 ; ... ; f an bn |]

然后,由于多态性,您可以提升您的操作:

array_map2 (+) : int array -> int array -> int array
array_map2 (+.) : float array -> float array -> float array