我需要计算foo n = maximumBy (comparing p) [1..n]
,其中p :: Int -> Int
很慢。但是我知道p n < n
对于所有的n > 0
并且想用这个事实来加速这个计算的方式如下:我计算p x
为x
为n
降到1
,记住当前的最大值。一旦我达到x
小于或等于当前最大值,我知道这个最大值必须是全局值,而且我已经完成了。简化递归的原地Haskell代码
所以我尝试看起来像这样:
foo n = go (0, 0) n where
go (c, _) 1 = c
go (c, c') !x = if c' >= x then c else go (c2, c'2) (x-1) where
x' = p x
(c2, c'2) = if c' >= x' then (c, c') else (x, x')
这工作,但看起来不是很习惯。所以我正在寻找更优雅的解决方案。你有什么建议吗?
摆脱对,使它'去XYN ...',我会pn'绑定'到一个名称(唐甚至不给编译器一个重新计算它的机会),否则这就是我所要做的。简单,清晰,高效。 – 2013-03-26 14:18:27
谢谢,取而代之的是你建议它绝对更好。无论如何,我必须承认,我对于使用let ...在绑定时犹豫不决,因为我真的不知道在我的第二个模式匹配中,(p n)是否会计算两次。如果我必须证明我的代码是正确的,那么我会认为Haskell本质上是懒惰的,这意味着它的评估策略是按需呼叫,并且定义为“按需呼叫是名称呼叫的备忘录版本”,那么它应该没问题,不是。诚然,按照您的建议使用允许绑定不会让任何疑问的地方,我已经在我的下面添加了您的建议。 – zurgl 2013-03-26 16:00:53
我会用'where'。 'go x y n | n == 1 || n <= y = x | pn> y = go n pn(n-1)|否则=去x y(n-1)其中pn = p n'。 – 2013-03-26 16:03:56