无限制列表的 elem 函数
列表理解 haskell
paar = [(a,b) | a<-[a | a<-[1..], mod a 3 == 0], b<-[b*b | b<-[1..]]]
a = 除数 3 b = 正方形
元素必须按公平顺序构造。
测试 >elem (9, 9801) 必须为 True
我的 Error
Main> elem (9, 9801) 测试
错误 - 垃圾收集无法回收足够的空间
如何使用 Cantor 的对角线参数来实现这一点?
谢谢
list comprehension haskell
paar = [(a,b) | a<-[a | a<-[1..], mod a 3 == 0], b<-[b*b | b<-[1..]]]
a = divisor 3
b = square
The Elements must be constructed by equitable order.
the test >elem (9, 9801) must be True
my Error
Main> elem (9, 9801) test
ERROR - Garbage collection fails to reclaim sufficient space
How can I implement this with Cantor's diagonal argument?
thx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不太确定你的目标是什么,但这就是你的代码崩溃的原因。
请注意,您是在任何其他对之前生成所有
(3, ?)
对。elem
函数的工作原理是从头开始线性搜索该列表。由于(3, ?)
对有无数个,因此您永远无法达到(9, ?)
对。此外,您的代码可能在某处保留了
paar
,从而阻止其被垃圾收集。这会导致elem (9, 9801) paar
不仅占用无限时间,而且占用无限空间,从而导致您所描述的崩溃。最终,您可能需要采取另一种方法来解决您的问题。例如,像这样:
或者找出一些其他搜索策略,而不是通过无限列表进行直接线性搜索。
Not quite sure what your goal is here, but here's the reason why your code blows up.
Notice you're generating all the
(3, ?)
pairs before any other. Theelem
function works by searching this list linearly from the beginning. As there are an infinite number of(3, ?)
pairs, you will never reach the(9, ?)
ones.In addition, your code is probably holding on to
paar
somewhere, preventing it from being garbage collected. This results inelem (9, 9801) paar
taking not only infinite time but also infinite space, leading to the crash you described.Ultimately, you probably need to take another approach to solving your problem. For example, something like this:
Or alternatively figure out some other search strategy than straight up linear search through an infinite list.
这是同一个列表的另一种排序(根据 hammar 的建议):
并且在操作中:
通过使用对角路径迭代所有可能的值,我们保证在有限的时间内到达每个有限点(尽管有些点仍然在有限的时间内)内存范围)。
不过,正如哈马尔在评论中指出的那样,这还不够,因为还需要
无限长的时间才能得到
False
答案。然而,我们对 paar 的元素有一个顺序,即当
(3*a,b^2)
出现在(3*c,d^2)
之前<代码>a + b < c + d。因此,要确定给定的对
(x,y)
是否在paar
中,我们只需检查配对
(p,q)
而p/3 + sqrt q <= x/3 + sqrt y
。为了避免使用
Floating
数字,我们可以使用稍微宽松的条件,即p <= x || q <= y
。当然
p> x&& q> y
意味着p/3 + sqrt q > > x/3 + sqrt y
,因此这仍将包含任何可能的解决方案,并且保证会终止。所以我们可以构建这个检查
并使用它:
Here's an alternate ordering of the same list (by hammar's suggestion):
and in action:
By using a diagonal path to iterate through all the possible values, we guarantee that we reach each finite point in finite time (though some points are still outside the bounds of memory).
As hammar points out in his comment, though, this isn't sufficient, as it will still take
an infinite amount of time to get a
False
answer.However, we have an order on the elements of paar, namely
(3*a,b^2)
comes before(3*c,d^2)
whena + b < c + d
. So to determine whether a given pair(x,y)
is inpaar
, we only have to checkpairs
(p,q)
whilep/3 + sqrt q <= x/3 + sqrt y
.To avoid using
Floating
numbers, we can use a slightly looser condition, thatp <= x || q <= y
.Certainly
p > x && q > y
impliesp/3 + sqrt q > x/3 + sqrt y
, so this will still include any possible solutions, and it's guaranteed to terminate.So we can build this check in
And use it: