在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
,然后在这些函数中进行案例分析?