首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >你怎么知道何时使用折叠左,何时使用折叠-右?

你怎么知道何时使用折叠左,何时使用折叠-右?
EN

Stack Overflow用户
提问于 2009-09-18 11:22:40
回答 4查看 26.1K关注 0票数 109

我知道,左折叠产生左倾树,右产生右倾树,但当我伸手去折叠时,我有时会陷入头痛的困扰,试图确定哪种折叠是合适的。通常,我最终会解开整个问题,并逐步完成折叠函数的实现,因为它适用于我的问题。

所以我想知道的是:

  • 决定是左折还是右折的经验法则是什么?
  • 考虑到我面临的问题,我如何快速决定使用哪种折叠方式?

Scala的例子 (PDF)中有一个例子,使用折叠来编写一个名为flatten的函数,它将一个元素列表连接到一个列表中。在这种情况下,正确的折叠是正确的选择(考虑到列表连接的方式),但我必须考虑一下才能得出这个结论。

由于折叠是(函数式)编程中的一个常见动作,我希望能够快速而自信地做出这些决定。所以..。有小费吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-09-18 11:40:11

您可以将折叠转换为infix运算符表示法(在中间写入):

此示例使用累加器函数x折叠。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fold x [A, B, C, D]

因此等于

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A x B x C x D

现在,您只需对运算符的相联性进行推理(使用括号!)。

如果您有一个left-associative运算符,您将设置如下括号

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
((A x B) x C) x D

在这里,您使用一个左折叠。示例(haskell风格的伪码)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
foldl (-) [1, 2, 3] == (1 - 2) - 3 == 1 - 2 - 3 // - is left-associative

如果您的操作符是右关联的(右折叠),则括号的设置如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A x (B x (C x D))

示例:Cons-运算符

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
foldr (:) [] [1, 2, 3] == 1 : (2 : (3 : [])) == 1 : 2 : 3 : [] == [1, 2, 3]

一般来说,算术运算符(大多数运算符)是左联想的,所以foldl比较普遍.但在其他情况下,infix表示法+括号是非常有用的。

票数 119
EN

Stack Overflow用户

发布于 2009-09-18 12:55:27

奥林·希弗斯用"foldl是基本列表迭代器“和"foldr是基本列表递归运算符”来区别它们。如果你看看foldl是如何工作的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
((1 + 2) + 3) + 4

您可以看到正在构建的累加器(如尾递归迭代)。相反,foldr的收益是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 + (2 + (3 + 4))

在其中,您可以看到对基本大小写4的遍历,并从中构建结果。

所以我假设一个经验法则:如果它看起来像一个列表迭代,用尾递归的形式写起来很简单,那么foldl就是最好的选择。

但实际上,从你所使用的操作符的结合性来看,这可能是最明显的。如果他们是左联想,使用折叠。如果它们是正确的联想,使用foldr。

票数 68
EN

Stack Overflow用户

发布于 2009-09-19 13:10:58

其他海报给出了很好的答案,我不会重复他们已经说过的话。正如您在问题中给出的Scala示例,我将给出一个Scala的具体示例。正如戏法已经说过的那样,foldRight需要保留n-1堆栈帧,其中n是列表的长度,这很容易导致堆栈溢出--即使是尾部递归也无法避免这种情况。

一个List(1,2,3).foldRight(0)(_ + _)可以减少到:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 + List(2,3).foldRight(0)(_ + _)        // first stack frame
    2 + List(3).foldRight(0)(_ + _)      // second stack frame
        3 + 0                            // third stack frame 
// (I don't remember if the JVM allocates space 
// on the stack for the third frame as well)

List(1,2,3).foldLeft(0)(_ + _)将减少到:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(((0 + 1) + 2) + 3)

可以迭代计算,就像在List中所做的那样。

在像Scala这样经过严格评估的语言中,foldRight可以很容易地为大型列表打开堆栈,而foldLeft则不会。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scala> List.range(1, 10000).foldLeft(0)(_ + _)
res1: Int = 49995000

scala> List.range(1, 10000).foldRight(0)(_ + _)
java.lang.StackOverflowError
        at scala.List.foldRight(List.scala:1081)
        at scala.List.foldRight(List.scala:1081)
        at scala.List.foldRight(List.scala:1081)
        at scala.List.foldRight(List.scala:1081)
        at scala.List.foldRight(List.scala:1081)
        at scala.List.foldRight(List.scala:1081)
        at scala.List.foldRight(List.scala:1081)
        at scala.List.foldRight(List.scala:1081)
        at scala.List.foldRig...

因此,我的经验法则是--对于没有特定相联性的操作符,始终使用foldLeft,至少在Scala中是这样。否则,请参考答案中的其他建议;)

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

https://stackoverflow.com/questions/1446419

复制
相关文章
何时使用Serverless,何时使用Kubernetes
我经常被问到的一个问题是:我应该使用Serverless还是Kubernetes来构建云原生应用程序?两种计算选项都有利有弊,这取决于您的需求,您应该选择哪种选项。
February
2018/11/23
1.7K0
MySQL索引的分类、何时使用、何时不使用、何时失效?
MySQL索引分为普通索引、唯一索引、主键索引、组合索引、全文索引。索引不会包含有null值的列,索引项可以为null(唯一索引、组合索引等),但是只要列中有null值就不会被包含在索引中。
PHP开发工程师
2021/05/21
8570
MySQL索引的分类、何时使用、何时不使用、何时失效?
MySQL 索引的分类、何时使用、何时不使用、何时失效?
blog.csdn.net/weixin_39420024/article/details/80040549
用户1516716
2021/03/23
1K0
何时使用或何时不使用malloc函数
在初学数据结构时,我们往往不太清楚在定义一个结构体指针时要不要使用malloc函数。 例如以下的代码:
全栈程序员站长
2022/06/26
5600
何时使用Java Stream,何时使用Java集合框架
Java 8 的Stream API 提供了不少可替代Java 集合框架的操作。但是不少同学在学习和使用Stream时依然感到很困惑,不知道何时使用Stream,甚至想不起来使用Stream,甚至在Stream和集合框架的选择上也成了问题。今天胖哥将尝试帮你解决这些疑问。
码农小胖哥
2021/04/26
7820
何时使用margin和padding?
margin和padding的意义相信大家都很清楚,可是在具体应用中,到底应该使用哪一个,就比较难于判断了。 这篇文章 说得挺清楚的,在这里翻译一下,供参考。
Java架构师必看
2021/03/22
7020
Go 何时使用泛型
Go 泛型设计者 Ian Lance Taylor 在官方博客发表了一篇文章 When To Use Generics,详细说明了在什么场景下应该使用泛型,什么场景下不要使用泛型。这对于我们编写 Go 泛型代码非常有指导意义。
恋喵大鲤鱼
2023/01/07
6250
何时不应使用深度学习?
来源 | hyperparameter.space 编译 | 聂震坤 我知道以深度学习的缺点来开始本文是不合时宜的,但是近几天关于深度学习的一大波讨论我觉得可以很好的引出我观点。一切都是从 Jeff Leek 于 Simply Stats 博客 发表的一篇关于在小样本规模体系中使用深度学习的注意事项文章开始。 简而言之,Jeff Leek 认为当样本规模很小的时候(通常在生物领域很常见),参数较小的线性模型甚至比拥有少量分层和隐藏单元的深网表现更好。为了证明自己的观点,Jeff 展示了一个拥有十个最常见信息
用户1737318
2018/07/20
4540
何时使用Entity或DTO
JPA和 Hibernate允许你在 JPQL和 Criteria查询中使用 DTO和 Entity作为映射。当我在我的在线培训或研讨会上讨论 Hibernate性能时,我经常被问到,选择使用适当的映射是否是重要的? 答案是:是的!为你的用例选择正确的映射会对性能产生巨大影响。我只选择你需要的数据。很明显,选择不必要的信息不会为你带来任何性能优势。
乱敲代码
2019/07/17
1.9K0
何时使用Entity或DTO
你应该知道的折叠屏手机适配
从目前推出的这几款折叠手机可以看出:折叠手机从折叠到展开,屏幕的变化类似于 iphone 到 ipad。
WecTeam
2019/12/16
2.1K0
你应该知道的折叠屏手机适配
何时使用Elasticsearch而不是MySql
MySQL 和 Elasticsearch 是两种不同的数据管理系统,它们各有优劣,适用于不同的场景
wayn
2023/08/28
3020
何时使用Elasticsearch而不是MySql
何时使用MongoDB而不是MySql
MySQL 和 MongoDB 是两个可用于存储和管理数据的数据库管理系统。MySQL 是一个关系数据库系统,以结构化表格格式存储数据。相比之下,MongoDB 以更灵活的格式将数据存储为 JSON 文档。两者都提供性能和可扩展性,但它们为不同的应用场景提供了更好的性能。
wayn
2023/08/09
1K0
何时使用MongoDB而不是MySql
何时使用Elasticsearch而不是MySql
MySQL 和 Elasticsearch 是两种不同的数据管理系统,它们各有优劣,适用于不同的场景。本文将从以下几个方面对它们进行比较和分析:
wayn
2023/08/09
6880
何时使用Elasticsearch而不是MySql
何时使用Kafka而不是RabbitMQ
Kafka 和 RabbitMQ 都是流行的开源消息系统,它们可以在分布式系统中实现数据的可靠传输和处理。Kafka 和 RabbitMQ 有各自的优势和特点,它们适用于不同的场景和需求。本文将比较 Kafka 和 RabbitMQ 的主要区别,并分析何时使用 Kafka 而不是 RabbitMQ。
wayn
2023/06/26
3540
何时使用Kafka而不是RabbitMQ
何时使用Kafka而不是RabbitMQ
Kafka 和 RabbitMQ 都是流行的开源消息系统,它们可以在分布式系统中实现数据的可靠传输和处理。Kafka 和 RabbitMQ 有各自的优势和特点,它们适用于不同的场景和需求。本文将比较 Kafka 和 RabbitMQ 的主要区别,并分析何时使用 Kafka 而不是 RabbitMQ。
wayn
2023/08/28
2580
何时使用Kafka而不是RabbitMQ
何时(不)使用Java抽象类
抽象类是许多面向对象语言的核心特性,例如Java。也许是因为这个原因,他们往往被过度使用,实际上被误用了。在本文中,我们将使用一些模式和反模式的示例来说明何时使用抽象方法,何时不使用。
程序猿DD
2019/05/10
1.2K0
何时(不)使用Java抽象类
小说python何时使用生成器
生成器、迭代器作为python的两个高级特性,相信大家肯定耳熟能详,都能说道上一阵,但很多时候都是说说而已,知道有这么个东西,而且是好东西,但再看看写过的代码,有多少确实使用它的?
用户2196567
2018/09/20
5730
Reddit 观察:你何时会考虑使用 Cpp 而非 Rust ?
一位同时使用过 Rust 和 Cpp 的开发者,他用 Rust 主要是实现 Web 服务器和命令行工具,而 Cpp 则用于游戏开发(虚幻引擎)和编写虚幻引擎插件。
张汉东
2023/09/13
3480
Reddit 观察:你何时会考虑使用 Cpp 而非 Rust ?
何时使用和不使用云原生安全工具
虽然主要云计算供应商提供的安全工具很方便,但这对一些用户来说并不意味着总是正确的选择。因此需要了解如何决定何时应选择使用第三方安全工具。哪种类型的云安全工具是最好的?其答案很大程度上取决于特定的云计算架构以及组织的安全需求的性质。
静一
2020/10/27
5220
何时使用和不使用云原生安全工具
何时使用中位数来进行分析?
我们通过计算,不管是面积还是租金偏斜度都达到了18以上,足够证明需要使用中位数来进行分析。
逍遥之
2020/03/23
6980

相似问题

这个scala函数是使用右折叠还是左折叠?

18

折叠右对左

15

知道NSPopoverTouchBarItem何时会显示其折叠视图

19

PostgreSQL何时将子查询折叠为联接,何时不折叠?

23

Scala中何时使用折叠和何时在列表中使用foreach

33
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

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

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文