Functional programming 在OCaml中使用数组实现堆栈时,如何保持多态性?

Functional programming 在OCaml中使用数组实现堆栈时,如何保持多态性?,functional-programming,ocaml,Functional Programming,Ocaml,我正在使用数组在OCaml中实现堆栈 我希望它可以接受任何类型。这是我实现的一部分,我的问题也是关于它的 因此,在上面,当我定义堆栈的类型时,它是好的。存储器是一个数组,它是一个可以接受任何类型的数组 但是当我实现create函数时,我遇到了问题。如何初始化数组的?我不能,对吗?当我创建它时,我必须给它一个初始值,对吗 那么如何使用具有多态性的数组创建堆栈?您可以延迟分配数组: type 'a stack = {mutable storage : 'a array option; muta

我正在使用
数组
OCaml
中实现
堆栈

我希望它可以接受任何类型。这是我实现的一部分,我的问题也是关于它的



因此,在上面,当我定义堆栈的类型时,它是好的。
存储器
是一个数组
,它是一个可以接受任何类型的数组

但是当我实现
create
函数时,我遇到了问题。如何初始化数组的
?我不能,对吗?当我创建它时,我必须给它一个初始值,对吗



那么如何使用具有多态性的数组创建堆栈?

您可以延迟分配数组:

type 'a stack = {mutable storage : 'a array option; mutable n : int}
let create () = {storage = None; n = -1}
然后,push函数将检查堆栈是否已经初始化,并创建not的数组


但是,更一般地说,我认为最好使用“列表引用”来定义堆栈。或者更好地使用不可变堆栈,即列表。

您可以延迟分配数组:

type 'a stack = {mutable storage : 'a array option; mutable n : int}
let create () = {storage = None; n = -1}
然后,push函数将检查堆栈是否已经初始化,并创建not的数组


但是,从更一般的角度讲,我认为最好使用“列表引用”来定义堆栈。或者更好的做法是使用不可变堆栈,即列表。

您的
存储
字段是可变的,因此您可以在不同的时间将不同的数组放在那里。因此,可以使用完全多态的空数组(如空列表)进行初始化

另一种方法是使用
存储
字段的选项类型,并在第一次推送操作时创建阵列

我有时会在我的生产代码中遇到这种问题。我通常使用选项类型

(更好的方法是使用堆栈列表。除非您需要访问顶部以外的元素,否则数组只会带来麻烦,不会带来任何好处。)

更新

这里有一个函数,它返回的数组是所提供数组的两倍大。为了灵活性,额外的元素不保证有任何特定的值(尽管实际上它们只是原始数组的第0个元素的副本)

let双数组=
设len=Array.length数组in
如果len=0,则数组(*2*0=0*)
其他的
Array.init
(2*len)
(乐趣x->if x
您的
存储
字段是可变的,因此您可以在不同的时间将不同的数组放在那里。因此,可以使用完全多态的空数组(如空列表)进行初始化

另一种方法是使用
存储
字段的选项类型,并在第一次推送操作时创建阵列

我有时会在我的生产代码中遇到这种问题。我通常使用选项类型

(更好的方法是使用堆栈列表。除非您需要访问顶部以外的元素,否则数组只会带来麻烦,不会带来任何好处。)

更新

这里有一个函数,它返回的数组是所提供数组的两倍大。为了灵活性,额外的元素不保证有任何特定的值(尽管实际上它们只是原始数组的第0个元素的副本)

let双数组=
设len=Array.length数组in
如果len=0,则数组(*2*0=0*)
其他的
Array.init
(2*len)
(乐趣x->if x
为什么要在OCaml中使用数组实现堆栈?这没有意义,这不是C++或java。不可变堆栈:

 type 'a stack = Empty | Stack of 'a * 'a stack

 let pop = function
   | [] -> raise (Invalid_argument "empty stack")
   | x :: s -> x, s

 let push x s = x :: s

 let is_empty s = (s = Empty)
type 'a stack = 'a list ref

let create () = ref []

let pop s =
  match !s with
    | [] -> raise (Invalid_argument "empty stack")
    | x :: xs -> s := xs ; x

let push x s = (s := x :: !s)

let is_empty s = (!s = [])
可变堆栈:

 type 'a stack = Empty | Stack of 'a * 'a stack

 let pop = function
   | [] -> raise (Invalid_argument "empty stack")
   | x :: s -> x, s

 let push x s = x :: s

 let is_empty s = (s = Empty)
type 'a stack = 'a list ref

let create () = ref []

let pop s =
  match !s with
    | [] -> raise (Invalid_argument "empty stack")
    | x :: xs -> s := xs ; x

let push x s = (s := x :: !s)

let is_empty s = (!s = [])

另外,在您声称阵列将以某种方式更快之前,您应该执行测试。

为什么要在OCaml中使用阵列实现堆栈?这没有意义,这不是C++或java。不可变堆栈:

 type 'a stack = Empty | Stack of 'a * 'a stack

 let pop = function
   | [] -> raise (Invalid_argument "empty stack")
   | x :: s -> x, s

 let push x s = x :: s

 let is_empty s = (s = Empty)
type 'a stack = 'a list ref

let create () = ref []

let pop s =
  match !s with
    | [] -> raise (Invalid_argument "empty stack")
    | x :: xs -> s := xs ; x

let push x s = (s := x :: !s)

let is_empty s = (!s = [])
可变堆栈:

 type 'a stack = Empty | Stack of 'a * 'a stack

 let pop = function
   | [] -> raise (Invalid_argument "empty stack")
   | x :: s -> x, s

 let push x s = x :: s

 let is_empty s = (s = Empty)
type 'a stack = 'a list ref

let create () = ref []

let pop s =
  match !s with
    | [] -> raise (Invalid_argument "empty stack")
    | x :: xs -> s := xs ; x

let push x s = (s := x :: !s)

let is_empty s = (!s = [])

另外,在您声称阵列将以某种方式更快之前,您应该执行测试。

如何创建空阵列?我在ArrayAh的API中看不到它,好吧,我理解,你的意思是a[| |].好吧,如果我必须调整数组的大小怎么办?如何编写我的
调整数组大小旧的\u ary新的\u len
?比如说,这个函数是为了创建一个新的数组,并从Java中的旧数组中复制所有元素,我想使用数组实现堆栈会更快,对吗?然而,在Java中使用数组时,如果数组已满,则必须将其大小加倍。我只是想在OCaml中实现同样的东西来练习我的OCaml技能。如果使用option,那么我必须使用None来编写匹配存储->…|一些ary->…?如何生成空数组?我在ArrayAh的API中看不到它,好吧,我理解,你的意思是a[| |].好吧,如果我必须调整数组的大小怎么办?如何编写我的
调整数组大小旧的\u ary新的\u len
?比如说,这个函数是为了创建一个新的数组,并从Java中的旧数组中复制所有元素,我想使用数组实现堆栈会更快,对吗?然而,在Java中使用数组时,如果数组已满,则必须将其大小加倍。我只是想在OCaml中实现同样的东西来练习我的OCaml技能。如果使用option,那么我必须使用None来编写匹配存储->…|如果我做一个不可变堆栈,那么对于pop我必须返回一个元组,而不仅仅是一个值,对吗?即使是官方的堆栈模块也不是一成不变的。否则,您可以将
pop
top
函数分开。“官方”堆栈模块是可变的,因为不可变的堆栈已经以列表的形式存在如果我使用不可变堆栈,那么对于pop,我必须返回一个元组,而不仅仅是一个值,对吗?即使是官方的堆栈模块也不是一成不变的。否则,您可以将
pop
top
函数分开。“官方”堆栈模块是可变的,因为不可变堆栈已经以