Haskell 的评估速度比我想象的要快得多(没有提示)

标签 haskell lazy-evaluation

我写了下面的代码来检查一个数是否是质数:

factorsOf :: Int -> [Int]
factorsOf n = [factor | factor <- [2..sqrtOfN], n `rem` factor == 0]
    where sqrtOfN = round . sqrt $ fromIntegral $ n+1

isPrime :: Int -> Bool
isPrime n
    | factorsOf n == [] = True
    | otherwise = False

它有效,但我注意到一些奇怪的事情。如果我对一个大数(比如 100000001)运行 factorsOf,计算所有因子需要几秒钟。如果我在同一个数字上运行 isPrime,如果它找到一个因子,它几乎会立即返回。 Haskell 是否真的跟踪函数将返回以支持(我假设)惰性评估的条件?如果这是真的,那就太棒了。

最佳答案

如注释中所述,isPrime 只需要足够深入地评估 factorsOf 的结果以确定它是否为空列表。您可以像这样更惯用地编写 isPrime:

isPrime = null . factorsOf

null 就是

null (_:_) = False
null _ = True

请注意,一旦 null 可以在 (:) 构造函数上进行模式匹配,它就会返回一个结果,而不会评估列表的其余部分。

这意味着只有 factorsOf 只需要计算返回的 isPrime 的第一个因子,而 factorsOf 本身将计算整个列表.

关于Haskell 的评估速度比我想象的要快得多(没有提示),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24263611/

相关文章:

javascript - 是否对 promise 进行了惰性评估?

wpf - 如何使 WPF TreeView 数据绑定(bind)惰性和异步?

c++ - Xtensor中的惰性评估

haskell - Haskell `seq` 算子的时间成本

javascript - 下划线或lazy.js 映射 (0,1,2,3,4) + (1,2,3,4,5) ->(1,3,5,7,9)

json - 使用 Aeson 的 `genericToJSON` 将产品类型编码为对象,而不是列表

Haskell - 生成节点之间的所有路径

haskell - 发生检查: cannot construct the infinite type

collections - Haskell "collections"语言设计

haskell - 了解 Haskell 中的 Fix 数据类型