社区首页 >问答首页 >F#中不可变的数据结构

F#中不可变的数据结构
EN

Stack Overflow用户
提问于 2018-03-05 06:52:55
回答 2查看 359关注 0票数 1

我试图在F#中使用它内置的泛型类型实现一个非常简单的堆栈。从命令式范式来看,有时很难想象如何避免易变性。

到目前为止,我使用pushpop运算符提供了一个简单的数据结构:

代码语言:javascript
代码运行次数:0
复制
type Stack<'a> =
    | Empty
    | S of 'a list
with
member L.Push x =
    match L with
    | Empty | S ([]) -> S ([x])
    | S (V) ->  S (x :: V)
member L.Pop = 
    match L with
    | Empty | S ([]) -> failwith "Error: Stack is empty"
    | S (v::_) -> v
end

我的想法是让Stack持有一个S of 'a list,在这里,我们用con ::操作符修改列表,使其不是对列表S进行变异,而是将其替换为S'。到目前为止,堆栈最多只能有一个元素,并且当将元素推到它时它不会增长--同样,当弹出时也不会收缩。

有人能给我一个提示,说明如何重写结构/以不同的方式思考它吗?

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2018-03-05 07:13:12

您可以通过简单地让一个列表充当堆栈,从而以一种更实用的方式来实现这一点。您可以将pushpop改为函数,而不是方法。

代码语言:javascript
代码运行次数:0
复制
// Returns the new stack
let push item stack = item :: stack

// Returns (item, newStack) tuple or throws if stack is empty
let pop stack =
    match stack with
    | [] -> failwith "Stack is empty"
    | item :: newStack -> item, newStack


// Example usage

let stack = []

let populatedStack = push "hello" stack
// populatedStack = ["hello"]

let item, emptiedStack = pop populatedStack
// item = "hello"
// emptiedStack = []
票数 5
EN

Stack Overflow用户

发布于 2018-03-09 01:54:49

内置不可变列表已经是一个有效的堆栈结构。推送操作是::,使用模式匹配(如let (first,rest) = list )获得最后一项

如果你想从头开始创建一个堆栈。以下是一些实现。

1)

( a)堆栈不是空的

( b)或对前一个堆栈的值和引用。

代码语言:javascript
代码运行次数:0
复制
type Stack<'a> =
    | Empty
    | Value of 'a * Stack<'a>

module Stack =
    let isEmpty = function
        | Empty   -> true
        | Value _ -> false
    let empty = Empty
    let push x stack = Value (x, stack) 
    let pop (Value (x, stack)) = x, stack


let stk =
    Stack.empty
    |> Stack.push 1
    |> Stack.push 2
    |> Stack.push 3

let rec loop stack =
    if   Stack.isEmpty stack
    then ()
    else
        let first, rest = Stack.pop stack
        printfn "First: %d" first
        loop rest

loop stk

您还可以选择一个记录作为底层数据结构。

代码语言:javascript
代码运行次数:0
复制
type Stack<'a> = {
    Value: 'a option
    Next:  Stack<'a> option
}

这样,一个包含三个元素的堆栈看起来就像。

代码语言:javascript
代码运行次数:0
复制
{Value=Some 3; Next=
    {Value=Some 2; Next=
        {Value=Some 1; Next=
            {Value=None; Next=None}}}}

您还可以选择一个带有valuenext字段的类,并使用null作为最后一个元素。

重要的是如何处理这些结构。使用不可变数据结构的方法是使用递归函数而不是循环。

创建一个访问每个元素并在每个元素上执行函数的尾递归函数是fold函数,类似于一个forEach

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49113155

复制
相关文章
js|jq获取兄弟节点,父节点,子节点
08.19自我总结 js|jq获取兄弟节点,父节点,子节点 一.js var parent = test.parentNode; // 父节点 var chils = test.childNodes; // 全部子节点 var first = test.firstChild; // 第一个子节点 var last = test.lastChile; // 最后一个子节点  var previous = test.previousSibling; // 上一个兄弟节点 var next = test.next
小小咸鱼YwY
2019/09/11
15.1K0
jquery 获取元素(父节点,子节点,兄弟节点)
1、jquery 获取元素(父节点,子节点,兄弟节点) $("#test1").parent(); // 父节点 $("#test1").parents(); // 全部父节点 $("#test1").parents(".mui-content"); $("#test").children(); // 全部子节点 $("#test").children("#test1"); $("#test").contents(); // 返回#test里面的所有内容,包括节点和文本 $("#test").content
biaoblog.cn 个人博客
2022/08/11
5.6K0
nvue获取节点信息
我们生活在阴沟里,但依然有人仰望星空。——王尔德 在nvue中我们获取节点信息就需要如下写法: <template> <view ref="list-parent" class="ruben"> <list> <cell><view>阿超</view></cell> </list> </view> </template> <script> const dom = weex.requireModule('dom'); export default { data() { return
阿超
2022/08/21
1.5K0
nvue获取节点信息
php获取所有节点的父节点和子节点
根据子节点获取所有的父节点以及父节点的父节点.. <?php $src = '[{"id":"1","name":"媒体(白名单)","pid":"0"},{"id":"2","name":"党媒公
黄啊码
2020/05/29
6.2K0
MySQL连接错误
ERROR 1045 (28000): Access denied for user’root’@’localhost’(using password:YES)
一点儿也不潇洒
2018/08/07
3.6K0
MySQL连接错误
xpath库详解xpath入门获取所有节点 //子节点 /父节点 ..属性匹配 @文本获取按序选择节点轴选择
python爬虫抓取网页内容,需要对html或xml结构的数据进行解析,如果用正则,单是写正则表达式就让很多望而生畏了。
章鱼喵
2018/09/26
25.2K0
xpath库详解xpath入门获取所有节点 //子节点 /父节点 ..属性匹配 @文本获取按序选择节点轴选择
XML获取当前节点信息
%XML.Node的以下字符串属性。提供关于当前节点的信息。 在所有情况下,如果没有当前节点,将抛出一个错误。
用户7741497
2022/07/05
1.6K0
【Debug】npm下载报错:npm ERR! code ETIMEDOUT npm ERR! syscall connect npm ERR! errno ETIMEDOUT
网络问题😶‍🌫️ npm的默认地址是国外的,在下载依赖时,由于网速问题可能会导致这样那样的错误~ # 查看自己的安装源 npm config get registry # 更换npm源为国内淘宝镜像 npm config set registry http://registry.npm.taobao.org/ # 或者国内npm官方镜像 npm config set registry http://registry.cnpmjs.org/ # ----- 还原npm源 ------ npm co
且陶陶
2023/04/12
4.4K0
【Debug】npm下载报错:npm ERR! code ETIMEDOUT npm ERR! syscall connect npm ERR! errno ETIMEDOUT
Java连接SqlServer错误
这次使用的是 SqlServer 数据库,之前并没有使用过,但是问题不大,我按照需求文档的步骤连接好 SqlServer 之后,启动 SpringBoot 项目,发现了一个报错,如下:
程序员Leo
2023/08/07
4900
Java连接SqlServer错误
qttreewidget详解_qtreewidget获取节点层级
1:通过findItems 过滤出符合条件的item 只是用于简单的过滤,复杂的效果不太好, 推荐第二种
全栈程序员站长
2022/11/15
2.8K0
qttreewidget详解_qtreewidget获取节点层级
inode节点--软硬连接和作用
一般情况下,文件名和inode号码是”一一对应”关系,每个inode号码对应一个文件名。但是,Unix/Linux系统允许,多个文件名指向同一个inode号码。
陈不成i
2021/05/25
1.2K0
【JavaScript】获取对应的节点总结
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="dv"> <ul id="uu"> <li>第一个</li> <li>第二个</li>嘎嘎 <li id="three">第三个</li>哈哈 <li>第四个</li> <li>第五个</li> </ul> </div> <script
游魂
2018/06/08
1.4K0
vue是如何获取元素节点 ?
Js中:用document.getElement之类的语句来操作dom; vue:使用vue提供的api,用 ref 来获取节点;
青梅煮码
2023/01/16
2.8K0
SQL根据指定节点ID获取所有父级节点和子级节点
根据指定节点ID获取所有父节点 with temp as( select * from dbo.Category where Id=493 --表的主键ID union all select t.* from temp,dbo.Category t where temp.Pid=t.Id --父级ID=子级ID )select * from temp order by Level; [查询结果] 根据指定节点ID获取所有子节点 with temp as( select * from dbo.Category
段邵华
2019/08/01
6K0
获取DOM节点的方法汇总
我们都知道,当获得所有节点(如:getElementsByTagName)或者获得所有子元素(如:element.childNodes)时,实际上返回的是包含一些DOM节点的集合,这个集合要么是 HTMLCollection,要么是 NodeList,两者其实都是类数组的对象。
Chor
2019/11/07
4.3K0
JavaScript之怎样获取元素节点
JavaScript获取元素节点一共有三种方法,分别是通过元素ID、通过标签名字和通过类名字来获取; 1.通过元素ID属性的ID值来获得元素对象-getElementById() DOM提供了一个名为getElementById()的方法,这个方法将返回一个与括号里有着一样id值的元素节点对应的对象。他是document对象特有的函数,这个函数的参数只有一个,只能是你想要获得的元素的ID值,这个值必须放在单引号或者双引号里面。 注意:JavaScript语言区分字母大小写,所以在写getElementByI
郑小超.
2018/01/24
1.3K0
树形结构已知子节点获取子节点所有父节点——任意目录/树
JS 树形结构 根据子节点找到所有上级,比如element-tree,已知路由上的子结点id,如何回填的 展开目录树?
周陆军博客
2023/05/07
3.3K0
element tree 获取当前节点和其父级节点的数据
需求:树形菜单点击之后需要形成面包屑,所以需要当前节点和其父级节点的数据。记录一下解决方法,如下。
用户7741497
2022/03/06
2.7K0
MYSQL vs JAVA 连接错误
最近开发告诉我,他们在测试系统的时候,会经常有连接MYSQL的连接被踢掉。具体给我的解释是,JAVA的缓冲池连接MYSQL 保持连接,但再次使用的时候,报连接错误。
AustinDatabases
2019/07/12
3.9K0
MYSQL  vs JAVA 连接错误
java根据子节点获取它对应的所有父节点_java根据父节点查找子节点
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/10/01
6.9K0

相似问题

将ereg_replace转换为preg_replace

21

将此ereg_replace转换为preg_replace

19

将eregi转换为preg_match,将ereg_replace转换为preg_replace

18

将ereg_replace更改为preg_replace

10

在php中将ereg_replace转换为preg_replace

12
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档