【发布时间】:2010-07-08 22:28:57
【问题描述】:
首先,为模糊的标题道歉,但我不确定究竟我在这里问什么(!)。
在大学遇到 Haskell 后,我最近开始在愤怒中使用它,所以我正在解决 Project Euler 问题作为扩展的 Hello World,真的。我在我的一个答案中遇到了一个错误,这似乎表明对语言的基本部分存在误解,这不是我可以从教程中解决的问题,也不是我对开始谷歌搜索的足够了解。
问题本身的简要描述 - 解决方案与素数有关,所以我想要一个我实现的素数的无限列表(还没有优化!)因此:
isPrime :: Int -> Bool
isPrime n = isPrime' 2 n
where isPrime' p n | p >= n = True
| n `mod` p == 0 = False
| otherwise = isPrime' (p+1) n
primes :: [Int]
primes = filter isPrime [2..]
由于评估无限列表可能有点乏味,我当然会使用惰性评估来确保只评估我想要的位。因此,例如,我可以向 GHCI 询问小于 100 的素数:
*Main> takeWhile (< 100) primes
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
现在这是我完全不明白的部分 - 当上限变得足够大时,我根本没有得到任何答案。特别是:
*Main> takeWhile (< 4000000000) primes
[]
这不是takeWhile 本身的问题,也不是部分应用的函数,因为takeWhile (< 4000000000) [2..] 按我的预期工作。我使用过滤器(在primes 的定义内)没有问题,因为takeWhile (< 4000000000) (filter even [2..]) 也返回预期结果。
通过二分搜索,我发现最大的上限是2^31 - 1,所以这似乎意味着某种基于空间的约束(即最大的正符号整数)。然而:
- 我的印象是 Haskell 对整数的大小没有语言限制,它们仅受可用内存量的限制。
- 这个数字只出现在小于谓词中,我知道它至少在某些情况下可以按预期工作。当然,当它应用于列表的元素时,它不应该关心它们来自哪里?只看第一个元素,我知道当输入
2来自filter even [2..]时,谓词返回 true;我知道primes返回2作为它的第一个元素。那么我的列表怎么可能是空的,这个谓词怎么会失败“对于某些值 2”?
任何想法都将不胜感激,因为我没有足够的经验知道从哪里开始。感谢您抽出宝贵时间查看。
【问题讨论】: