【发布时间】:2014-11-09 05:56:06
【问题描述】:
我编写了以下函数来判断一个数是否为素数。
isPrime :: Int -> Bool
isPrime n = and (map (\x -> (n `mod` x > 0))[2..(intSquareRoot n)])
intSquareRoot :: Int -> Int
intSquareRoot n = intSq n
where
intSq x
| x*x > n = intSq (x - 1)
| otherwise = x
我刚开始使用 Haskell,所以这段代码对于任何受过使用训练的人来说可能都是可怕的。但是,我很好奇这段代码是否利用了 Haskell 的惰性求值。这部分
(map (\x -> (n `mod` x > 0))[2..(intSquareRoot n)])
将创建一个布尔值列表,如果其中一个为 False(因此,如果一个介于 2 和 n 的 sqrt 之间的数字除以 n),那么使用 'and' 函数整个事情都是 False。但我认为将首先创建整个列表,然后使用'and'函数。这是真的?如果是这样,我怎样才能通过使用惰性评估来加快速度,以便函数在找到 n 的第一个除数时停止并返回 false。提前感谢您的帮助!
【问题讨论】:
-
我会在
map之前使用$而不是括号;这真是一个不错的工具:) -
你可以用
any代替and:any (\x -> nmod` x > 0) [2..intSquareRoot n].any`相当于:any f = and . map f。 -
@Bakuriu 其实是
any f = or . map f。你想的是all f = and . map f。 -
intSquareRoot对于任何类型的大型输入都会难以置信缓慢。相反,您可能需要考虑基于旧的除平均技巧的循环。
标签: haskell functional-programming lazy-evaluation