您可能会发现Data.MemoCombinators很有用(在 data-memocombinators 包中)。
你没有说你f
和g
采取什么参数类型——如果它们都采用整数值,那么你会像这样使用它:
import qualified Data.MemoCombinators as Memo
foo = iterate step (Memo.integral f0, Memo.integral g0)
如果需要,您也可以记住每个步骤的输出
step (f,g) = (Memo.integral (newF f g), Memo.integral (newG f g))
我希望你不要把这看作是把整个程序撕成碎片。
回复您的评论:
这是我能想到的最好的。它未经测试,但应该沿着正确的路线工作。
我担心在 and 之间进行转换Double
是Rational
不必要的低效 --- 如果有一个我们可以使用的Bits
实例。因此,这最终可能对您没有任何实际用途。Double
Memo.bits
import Control.Arrow ((&&&))
import Data.Ratio (numerator, denominator, (%))
memoV :: Memo.Memo a -> Memo.Memo (V a)
memoV m f = \(V x y z) -> table x y z
where g x y z = f (V x y z)
table = Memo.memo3 m m m g
memoRealFrac :: RealFrac a => Memo.Memo a
memoRealFrac f = Memo.wrap (fromRational . uncurry (%))
((numerator &&& denominator) . toRational)
Memo.integral
一种不同的方法。
你有
step :: (V Double -> V Double, V Double -> V Double)
-> (V Double -> V Double, V Double -> V Double)
你把它改成
step :: (V Double -> (V Double, V Double))
-> (V Double -> (V Double, V Double))
step h x = (r fx gx, s fx gx)
where (fx, gx) = h x
也改变
foo = (fst . bar, snd . bar)
where bar = iterate step (f0 &&& g0)
希望共享fx
并且gx
应该会导致一些加速。