Ocaml 实现多态堆栈时遇到的问题

Ocaml 实现多态堆栈时遇到的问题,ocaml,Ocaml,我试图编写一个作为函子的PolishCalculator,它接收堆栈实现,遵循StackADT接口,并使用它来计算以该符号编写的表达式 因此,我开始为堆栈编写接口,它如下所示: module type StackADT = sig type 'a stack val empty : 'a stack val pop : 'a stack -> 'a val push : 'a -> 'a stack -> unit val is_emp

我试图编写一个作为函子的PolishCalculator,它接收堆栈实现,遵循StackADT接口,并使用它来计算以该符号编写的表达式

因此,我开始为堆栈编写接口,它如下所示:

module type StackADT = 
sig
    type 'a stack
    val empty : 'a stack
    val pop : 'a stack -> 'a
    val push : 'a -> 'a stack -> unit
    val is_empty : 'a stack -> bool
end;;
然后我尝试了一个具体的实现,如下所示:

module MyStack : StackADT = 
struct
    type 'a stack = {mutable c: 'a list}

    exception EmptyStackException

    let empty = {c = []}

    let pop stack = match stack.c with
    |[]-> raise EmptyStackException
    |h::tl -> stack.c <- tl; h

    let is_empty stack = match stack.c with
    |[] -> true
    |_ -> false 

    let push n stack = stack.c <- n::stack.c
end;;
我理解问题在于,在具体的实现中,直到我们将一个元素放入堆栈中,堆栈的类型才确定,而接口要求在调用empty之后堆栈已经被类型化,但是有什么方法可以让这件事情工作吗


感谢您在界面中编写以下内容:

val empty: 'a stack
您正在声明只有一个空堆栈,并且可以从该共享空堆栈开始构建任何堆栈

这不是实现中发生的情况,因为类型
'a堆栈
是可变的

一种修复方法是用空值生成器替换此空共享值:

val empty: unit -> 'a stack

感谢您修复工作正常,我还必须将MyStack empty函数编辑为
let empty()={c=[]}
,因此基本上就像我最初编写的那样,我声明调用empty将返回对唯一空堆栈的引用?我理解对了吗?根本没有电话。所以你说StackADT类型的模块必须提供一个空值,并且模块的所有用户共享一个且只有一个可变字段。将empty定义为`+堆栈(对不起,我记不清确切的语法)也行吗。空列表是任何列表的有效起点,就像空堆栈可用于任何类型一样。可变单元格对于其内容类型是不变的,因为它们既可以读取也可以写入。如果用户A将一个函数推到空堆栈,然后用户B推一个int,那么您不希望让A尝试读回其函数并获取B的int。
val empty: unit -> 'a stack