dxh*_*dxh 1 haskell tail-recursion pattern-matching fibonacci lazy-evaluation
这是一个Haskell函数,它接受一个数字n并返回第n个斐波纳契数.(我使用了索引方案,使得第0个数字为0,第1个数字为1,第2个数字为1,第3个数字为2,依此类推.)
fib :: (Integral a) => a -> a
fib 0 = 0
fib n = fibhelper n 0 1
fibhelper :: (Integral a) => a -> a -> a -> a
fibhelper 1 x y = y
fibhelper n x y = fibhelper (n-1) y (x+y)
Run Code Online (Sandbox Code Playgroud)
现在,假设为了效率,我想绕过Haskell的懒惰评估并强制评估更新的参数(例如使用$!运算符?)最优雅/惯用的方法是什么?
您可以使用爆炸模式来执行此操作.
{-# LANGUAGE BangPatterns #-}
fib :: (Integral a) => a -> a
fib 0 = 0
fib n = fibhelper n 0 1
-- Everything with a ! before it will be evaluated before the function body
fibhelper :: (Integral a) => a -> a -> a -> a
fibhelper 1 _ (!y) = y
fibhelper (!n) (!x) (!y) = fibhelper (n-1) y (x+y)
-- The above line is equivalent to:
--fibhelper n x y = n `seq` x `seq` y `seq` fibhelper (n-1) y (x+y)
Run Code Online (Sandbox Code Playgroud)
另请注意,使用Integral类型类时有点过于热心.你真的希望斐波那契数列的索引与值的类型相同吗?我建议您改为使用签名:
fib :: (Integral a, Integral b) => a -> b
Run Code Online (Sandbox Code Playgroud)
此外,如果您正在寻找性能,Integral应完全避免使用.
| 归档时间: |
|
| 查看次数: |
358 次 |
| 最近记录: |