我想知道是否可以在OCaml中进行编译时检查以确保数组的长度正确。对于我的问题,我想在进行分段向量减法之前验证两个GPU 1-dim向量的长度是否相同。
let init_value = 1
let length = 10_000_000
let x = GpuVector.create length init_value and y = GpuVector.create 9 init_value in
let z = GpuVector.sub v1 v2
在这个例子中,我希望它抛出一个编译错误,因为x和y的长度不一样。由于我是OCaml菜鸟,我想知道如何实现这一目标?我猜我将不得不使用仿函数或camlp4(我之前从未使用过)
答案 0 :(得分:4)
您无法在OCaml中为arrays of length n
定义类型系列,其中n
可以具有任意长度。但是,可以使用其他机制来确保只有GpuVector.sub
个兼容长度的数组。
最简单的实现机制是为长度为9的GpuVector
定义一个特殊模块,你可以使用仿函数来概括9。以下是模块GpuVectorFixedLength
的示例实现:
module GpuVectorFixedLength =
struct
module type P =
sig
val length : int
end
module type S =
sig
type t
val length : int
val create : int -> t
val sub : t -> t -> t
end
module Make(Parameter:P): S =
struct
type t = GpuVector.t
let length = Parameter.length
let create x = GpuVector.create length x
let sub = GpuVector.sub
end
end
您可以通过说例如
来使用它module GpuVectorHuge = GpuVectorFixedLength.Make(struct let length = 10_000_000 end)
module GpuVectorTiny = GpuVectorFixedLength.Make(struct let length = 9 end)
let x = GpuVectorHuge.create 1
let y = GpuVectorTiny.create 1
然后编译器拒绝z
的定义:
let z = GpuVector.sub x y
^
Error: This expression has type GpuVectorHuge.t
but an expression was expected of type int array
因此,我们在类型系统中成功地反映了两个具有相同长度的数组的属性。您可以利用模块包含来快速实现完整的GpuVectorFixedLength.Make
仿函数。
答案 1 :(得分:2)
slap库实现了这种大小的静态检查(对于线性代数)。 整体方法描述为this abstract