我不确定如何搜索这个问题。
假设我在int array
s上使用了一堆函数,例如分组减去其中两个(如果它们具有相同的长度),依此类推。有没有惯用的方法来处理这个问题?我应该如何将int
(或其他类型)上的操作提升到int array
(或其他类型的数组)上的操作?我应该使用仿函数还是采取其他方法?
编辑:我希望能够将int
或float
等数值类型的算术运算提升到相应数组的算术运算。我还应该写这些函数吗?
答案 0 :(得分:3)
只需编写功能。没有必要使用仿函数或其他任何东西,只需保持简洁和简洁。可读性应该是主要优先事项。
如果您希望函数位于数组模块中,可以使用以下技巧:
module Array = struct
include Array
let diff xs ys = ys
end
现在你有一个模块Array
,包含所有现有功能,以及你的功能。当然,这不会改变真正的Array
模块,只会在词法范围内起作用。
如果你的算法足够通用,只能依赖某些特定的代数,那么你可以用模块类型抽象这个代数,并使用函子或一流模块用这个代数参数化你的代码。一个很好的例子是Container
接口中的sum
function。它使用第一类模块(打包为值的模块)进行参数化,必须实现commutative group代数(sum函数需要)。基本上,用法是这样的:
List.sum (module Int) ~f:ident [1;2;3;4]
或
Array.sum (module Int) ~f:ident [| 1;2;3;4|]
此外,稍后可以轻松地重写此代码,以采用将在下一版OCaml中提供的新modular implicits。
答案 1 :(得分:3)
您在两个列表中拥有这些'迭代器'对于列表。 我想他们对你想做的事情已足够了。
我猜你可以使用列表代替(或者将数组转换成列表然后再将它们转回去,但这听起来不必要),或者只是自己编写这些函数。
以下是一个例子:
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