在OCaml中扩展int数组功能

在OCaml中扩展int数组功能,ocaml,idioms,Ocaml,Idioms,我不太确定如何寻找这个问题 假设我在int数组s上使用了一组函数,比如按分量减去其中两个(如果它们的长度相同)等等。有没有一种惯用的方法来处理这个问题?如何将ints(或其他类型)上的操作提升为int数组s(或其他类型的数组)上的操作?我应该使用函子还是采取其他方法 编辑:我希望能够将诸如ints或floats等数字类型的算术运算提升到相应数组上的运算。我还应该写函数吗?写函数就行了。没有必要使用函子或其他任何东西,只要保持简单和简洁即可。可读性应该是首要任务 如果希望函数位于阵列模块中,可以使

我不太确定如何寻找这个问题

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


编辑:我希望能够将诸如
int
s或
float
s等数字类型的算术运算提升到相应数组上的运算。我还应该写函数吗?

写函数就行了。没有必要使用函子或其他任何东西,只要保持简单和简洁即可。可读性应该是首要任务

如果希望函数位于阵列模块中,可以使用以下技巧:

module Array = struct 
  include Array
  let diff xs ys = ys
end
现在您有了一个包含所有现有函数的模块
Array
,还有您的。当然,这不会改变真正的
数组
模块,只在词法范围内有效

使现代化 如果您的算法足够通用,仅依赖于某些特定的代数,则可以使用模块类型抽象此代数,并使用函子或一级模块使用此代数参数化代码。一个很好的例子是一个in
容器
接口。它由一类模块(打包成值的模块)参数化,该模块必须实现代数(求和函数需要代数)。基本上,用法是这样的:

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


此外,此代码稍后可以轻松重写,以采用下一版本OCaml中提供的新代码。

只需编写函数即可。没有必要使用函子或其他任何东西,只要保持简单和简洁即可。可读性应该是首要任务

如果希望函数位于阵列模块中,可以使用以下技巧:

module Array = struct 
  include Array
  let diff xs ys = ys
end
现在您有了一个包含所有现有函数的模块
Array
,还有您的。当然,这不会改变真正的
数组
模块,只在词法范围内有效

使现代化 如果您的算法足够通用,仅依赖于某些特定的代数,则可以使用模块类型抽象此代数,并使用函子或一级模块使用此代数参数化代码。一个很好的例子是一个in
容器
接口。它由一类模块(打包成值的模块)参数化,该模块必须实现代数(求和函数需要代数)。基本上,用法是这样的:

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


此外,此代码稍后可以轻松重写,以采用下一版本的OCaml中提供的新代码。

对于列表,您可以使用这些“两个列表上的迭代器”。 我想它们足够你做你想做的事了

我想您可以使用列表(或者将数组转换为列表并再次转换,但这听起来成本不必要),或者自己编写这些函数

以下是一个例子:

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 (+) : int array -> int array -> int array
array_map2 (+.) : float array -> float array -> float array

对于列表,您有这些“两个列表上的迭代器”。 我想它们足够你做你想做的事了

我想您可以使用列表(或者将数组转换为列表并再次转换,但这听起来成本不必要),或者自己编写这些函数

以下是一个例子:

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 (+) : int array -> int array -> int array
array_map2 (+.) : float array -> float array -> float array

是的,我一直依赖于自己编写这些函数,但是我还需要提升除
int
之外的类型的算术运算,所以手工完成这项工作变得很乏味。有什么想法吗?多态性是关键,不是吗?例如,您可以使用
array\u map2(+):int-array->int-array->int-array
。@Sheeft提供的
array\u map2
函数适用于所有类型,而不仅仅是int。啊,是的,这很有意义。谢谢。是的,我一直依赖于自己编写这些函数,但我还需要提升除
int
以外的类型的算术运算,因此手工操作变得很乏味。有什么想法吗?多态性是关键,不是吗?例如,您可以使用
array\u map2(+):int-array->int-array->int-array
。@Sheeft提供的
array\u map2
函数适用于所有类型,而不仅仅是int。啊,是的,这很有意义。谢谢。如果我想让
int-array
s和
float-array
s都使用这些函数,比如说,最好定义一个变量类型,比如
type num=int of int | float of float
,然后在这些函数中进行案例分析?那么如果我想让
int-array
s和
float-array
s都使用这些函数,比如说,最好定义一个变量类型,比如
type num=Int of Int | Float of Float
,然后在这些函数中进行案例分析?