Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >向递归定义的haskell函数添加内存

向递归定义的haskell函数添加内存
EN

Stack Overflow用户
提问于 2019-07-20 21:45:50
回答 1查看 99关注 0票数 4

我已经用Haskell解决了一个动态编程问题(实际上是一个Project Euler问题),归根结底是Fibonacci序列的推广:

代码语言:javascript
运行
AI代码解释
复制
 f(n) = f(n-1) + f(n-2)
 g(n) = g(n-1) + g(n-3)
 h(n) = h(n-1) + h(n-4)

还有更多类似的函数,由于问题的规模,我不得不添加memoization,这是相当琐碎的,如下所示:

代码语言:javascript
运行
AI代码解释
复制
memF = (map f' [0 ..] !!)
  where f' x | x <=1 = 1
        f' 2         = 2
        f' x         = memF(x-1) + memF(x-2)


memG = (map f' [0 ..] !!)
  where f' x | x <=2 = 1
        f' 3         = 2
        f' x         = memG(x-1) + memG(x-3)

这可以很好地工作,所以我可以像(memF 100) + (memG 100) + ...一样得到答案,并且我已经回答了这个问题,但是重复的代码很难看,我更愿意定义一个函数来生成记忆函数,比如:

代码语言:javascript
运行
AI代码解释
复制
mem d = (map f' [0 ..] !!)
  where f' x | x < d  = 1
        f' x | x == d = 2
        f' x          = (mem d) (x-1) + (mem d)(x-d)

然后回答这个失败,或者至少缓存不起作用,我猜因为每次调用都会重新创建数组,我想我可以使用StateMonad或memoization库,但我很有兴趣知道是否有一种方法可以在没有Monad的情况下做到这一点。有吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-20 21:56:54

您需要另一个绑定来避免对mem d的递归调用

代码语言:javascript
运行
AI代码解释
复制
mem d = g
  where g = (map f' [0 ..] !!)
        f' x | x < d  = 1
        f' x | x == d = 2
        f' x          = g (x-1) + g (x-d)

在调用mem时也要小心,因为每次调用mem都会创建自己的缓存。例如。

代码语言:javascript
运行
AI代码解释
复制
mem 10 x + mem 10 y

将不缓存任何内容,而

代码语言:javascript
运行
AI代码解释
复制
let g = mem 10 in g x + g y

将使用相同的缓存。

另一种方法是使用(d,x)对上的memoization,对所有调用mem d x使用一个“全局”缓存。不过,这看起来更难实现。

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

https://stackoverflow.com/questions/57128819

复制
相关文章
关于php递归函数内存溢出的问题
简单写一个递归函数: echo '运行前内存:' . round(memory_get_usage() / 1024 / 1024, 2) . 'MB', PHP_EOL; recursive(); function recursive($i=1000){     if ($i<=0){         return false;     }     $data = range(1,1000);     echo '运行中内存:' . round(memory_get_usage() / 1024 / 1
仙士可
2021/10/27
2.7K0
函数curry化(Haskell Curry)
当一个函数fn有多个参数时,可以先传入一部分参数,生成一个中继函数nextFn,然后在nextFn当中再传入剩下的参数。(一步curry化)
elson
2020/01/02
1.3K0
热爱函数式的你,句句纯正的 Haskell【函数篇】
Haskell 值与函数是统一的,函数只是需要其他参数输入的值。如果定义的是函数,那么这个函数的行为在运行过程中也是不会改变的,对于某一个特定的输入返回的结果总是确定的,这样的函数为纯函数。
掘金安东尼
2022/09/19
3590
使用Solr向您的站点添加自定义搜索
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。 文档通过Http利用XML 加到一个搜索集合中。查询该集合也是通过http收到一个XML/JSON响应来实现。它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮显示搜索结果,通过索引复制来提高可用性,提供一套强大Data Schema来定义字段,类型和设置文本分析,提供基于Web的管理界面等。
新巴子
2018/08/16
1.3K0
Python 函数:定义、调用、参数、递归和 Lambda 函数详解
可以将信息作为参数传递给函数。参数在函数名称后面的括号内指定。您可以添加任意数量的参数,只需用逗号分隔即可。以下示例具有一个参数(fname)的函数。调用函数时,我们传递一个名字,该名字在函数内用于打印全名:
小万哥
2023/10/22
2970
Python 函数:定义、调用、参数、递归和 Lambda 函数详解
【说站】JavaScript使用递归定义阶乘函数
如果函数有名字,而且名字以后也不会变,那么定义就没问题了。但问题是函数的执行与函数名factorial紧密耦合。
很酷的站长
2022/11/24
5670
【说站】JavaScript使用递归定义阶乘函数
热爱函数式的你,句句纯正的 Haskell【库函数篇】
本篇是笔记篇,介绍 Haskell 的强大的库函数,也可感受下与我们平常的 js 操作异同之处:
掘金安东尼
2022/09/19
4520
Casbin如何添加自定义函数
官方:https://casbin.org/docs/zh-CN/function
Tinywan
2023/03/08
9560
Casbin如何添加自定义函数
Haskell
这门语言在数学模型上有着很深的优势,虽然它有很多特性,让人很难接受,随着学习的深入,你才会发现这会多么有趣。
icepy
2019/06/24
8960
Haskell doctest
一定要注意格式 第一行很重要,-- |这行没有就不是一个 test。 可以对比 >>> 的个数 和 terminal里的 Examples 个数确认是否自己的所有 test 都测试了
莫听穿林
2022/05/20
3220
Haskell doctest
python第三十一课--递归(1.简单递归函数的定义和使用)
演示:简单递归函数的定义和使用 需求:1~5进行累加 找寻关系: 函数名:mySum(num) 1).找临界点:运算到1(加到1)就结束了 2). 第一次:5+mySum(5-1)-->return 5+10 第二次:4+mySum(4-1)-->return 4+6 10 第三次:3+mySum(3-1)-->return 3+3 6 第四次:2+mySum(2-1)-->return 2+1 3 第五次:1 -->return 1
hankleo
2020/09/16
5570
【算法】递归算法 ① ( 使用递归推导斐波那契数列 | 递归内存开销分析 | 递归三要素 : 定义 拆解 出口 )
斐波那契数列 : https://leetcode.cn/problems/fei-bo-na-qi-shu-lie-lcof/
韩曙亮
2023/03/30
4210
递归函数的优化
为什么会出现这种问题呢?原因就出在return num*factorial(num-1)这一句上,这种写法使得函数太过紧密,一旦将函数保存到另一个变量中,并将原变量设置为null,factorial便不再是函数,因此会报错。
IMWeb前端团队
2019/12/03
7190
递归函数[通俗易懂]
当然,你可以尝试会发生什么结果,理论上会永远运行下去,但实际操作时发现不一会儿程序就报错了,因为每次调用函数都会用掉一点内存,在足够多的函数调用发生后,空间几乎被占满,程序就会报错。
全栈程序员站长
2022/09/07
7340
递归函数[通俗易懂]
递归函数
这里使用的是命名函数表达式的方法实现递归,将这个函数赋值给 factorial 。这样即使在使用过程中对变量进行修改,也不会影响已赋值的递归函数进行调用,保证了代码的安全性。这种方式在严格模式和非严格模式下都适用。
就只是小茗
2018/12/12
7880
递归函数
递归就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身,每调用一次就进入新的一层。递归函数必须有结束条件。
大忽悠爱学习
2021/03/04
7210
Python 函数的递归
函数的递归 什么是递归函数 一个函数不停的将自己反复执行 递归的定义方法 通过返回值 直接执行自身函数 递归函数的说明 内存溢出 避免滥用递归 代码 # coding:utf-8 count = 0 def test(): global count count += 1 if count < 5: print('count条件不满足, 我要重新执行我自己! 当前count是%s' % count) return test() else:
Zkeq
2022/05/18
6610
递归函数的优化
本文介绍了递归函数在编程中的一种应用,利用递归函数实现阶乘的计算。同时探讨了递归函数中可能遇到的问题,以及解决方法。
IMWeb前端团队
2018/01/08
9760
函数递归
如果一个函数在内部调用自身本身,则该函数就是递归函数 递归优缺点   优点:使用递归函数的优点是逻辑简单清晰      理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰   缺点:过深的调用会导致栈溢出 栈溢出   使用递归函数需要注意防止栈溢出   在计算机中,函数调用是通过栈(stack)这种数据结构实现的   每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧   由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出 尾递归   解决递归调用栈溢出的方法是通过尾递归优化   事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的
py3study
2020/01/15
9640
WordPress 功能函数—— add_clean_index(向指定的表添加索引)
描述 向指定的表添加索引。 用法 add_clean_index( string $table, string $index ) 参数 $table (string)(必填)数据库表的名称。 $index (string)(必填)数据库表索引列。 返回 (true) 真,当执行完成时。 来源 文件:wp-admin/includes/upgrade.php function add_clean_index( $table, $index ) { global $wpdb;
.T.
2022/02/22
1.7K0

相似问题

haskell如何管理递归函数调用的内存?

13

Haskell递归和内存使用

31

Haskell向构造函数添加约束

12

在模板Haskell中定义递归函数

18

Haskell:递归定义函数值的有效计算

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

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

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文