【问题标题】:In Ocaml, is there a way to implement the function pop of a stack?在Ocaml中,有没有办法实现栈的pop函数?
【发布时间】: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

【问题讨论】:

    标签: stack ocaml


    【解决方案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]}
    #
    

    【讨论】:

      猜你喜欢
      • 2021-03-18
      • 2021-04-18
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-27
      • 2011-05-22
      相关资源
      最近更新 更多