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

Posted

技术标签:

【中文标题】在Ocaml中,有没有办法实现栈的pop函数?【英文标题】:In Ocaml, is there a way to implement the function pop of a stack? 【发布时间】:2022-01-05 02:24:00 【问题描述】:

我不想使用模块Stack,而是想自己构建一个弹出功能。

我实现的功能是:

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

【问题讨论】:

【参考方案1】:

您只需要返回一个没有弹出元素的新堆栈。此外,如果堆栈为空,但不在其他分支中,您将返回 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)

【讨论】:

谢谢!那么 1. 这个元组的功能是什么? 2.没有一些,为什么不起作用? 知道了,它是元组,因为我要返回两个参数,第一个参数是框架,第二个参数是堆栈列表。这是一些由于模块选项的数据结构。我可以通过定义一个 get 函数将 Some x 转换为 x。谢谢。 基本正确,但您可以只对 option 值进行模式匹配。它只不过是一个普通的变体类型:type 'a option = None | Some of 'aOption 模块只是一个容器,用于在 option 类型上运行的便捷函数。类型本身甚至没有在 Option 模块中定义,只是在其中使用别名,并且该模块没有对数据结构的特权访问。【参考方案2】:

暂时忽略它是惯用的还是复杂性的含义 - 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]
#

【讨论】:

以上是关于在Ocaml中,有没有办法实现栈的pop函数?的主要内容,如果未能解决你的问题,请参考以下文章

c++里关于栈的函数哪些常用

栈的操作

Java中有没有像C++中那种包含一个栈的头文件< stack >就可以用栈的一些出栈入栈的函数的做法?

OCaml:函数参数的默认值?

栈的最小值

OCaml 错误:“变体类型没有构造函数 ::”