在Ocaml中,有没有办法实现栈的pop函数?

In Ocaml, is there a way to implement the function pop of a stack?

我不想使用Stack模块,而是想自己构建一个pop函数。

我实现的功能是:

let pop (stack_lst:stack) = match stack_lst with
  | [] -> None
  | [x] -> x
  | hd::tl -> hd

很快我意识到我的函数只给出了顶层框架,但是,我的函数并没有从堆栈中移除顶层框架。从这个意义上说,框架仍然存在。 OCaml 给了我不可变的数据结构,我该怎么办?

除了我的问题,我的数据类型定义为:

location = Obj of int | Null
and
environment = (var * location) list
and
frame = Decl of environment | Call of environment * stack 
and 
stack = frame list

您只需要 return 一个没有弹出元素的新堆栈。此外,如果堆栈为空,您将 returning 一个 option,但在其他分支中不是,我也已在此处修复:

let pop (stack_lst: stack) = match stack_lst with
  | [] -> (None, [])
  | [x] -> (Some x, [])
  | hd::tl -> (Some hd, tl)

let pop (stack_lst: stack) = match stack_lst with
  | [] -> None
  | [x] -> Some (x, [])
  | hd::tl -> Some (hd, tl)

暂时忽略它是惯用的还是复杂的含义 - OCaml 确实 支持可变状态,这可用于解决堆栈之类的问题。

# type 'a stack = { mutable lst : 'a list };;
type 'a stack = { mutable lst : 'a list; }
# let a = { lst = [1; 3; 4] };;
val a : int stack = {lst = [1; 3; 4]}
# let pop = function
  | {lst=[]} -> None
  | {lst=(x::xs)} as s -> s.lst <- xs; Some x;;
val pop : 'a stack -> 'a option = <fun>
# pop a;;
- : int option = Some 1
# a;;
- : int stack = {lst = [3; 4]}
# pop a;;
- : int option = Some 3
# a;;
- : int stack = {lst = [4]}
#