我的想法是做一些事情:
class Memo1D m where -- for one-Dimensional function
memo1D :: m a -> [a]
instance Memo1D ((->) Int) where
memo1D f = map f [0 ..]
因此,将记忆添加到Integer-recursive-problem中将是非常通用的:
fib :: Int -> Int
fib 0 = 1
fib 1 = 1
fib n = (memo_fib !! (n - 1)) + (memo_fib !! (n - 2))
memo_fib = memo1D fib
此外,如果我还想在2-D函数中进行memoization,接收2 Integer作为参数,我必须添加更多代码((Int->Int->)
是错误,如何声明它?):< / p>
class Memo2D m where
memo2D :: m a -> [[a]]
instance Memo2D (Int -> Int ->) where -- (Int -> Int ->) is error, how to declare the kind that recieve `a` type and then become (Int->Int->a) ?
memo2D f = map (\v -> map v [0 ..]) (map f [0 ..])
&#34; 2-D fibnacci数&#34;记忆的编码如下:
fib2 0 0 = 1
fib2 0 1 = 1
fib2 1 0 = 1
fib2 i j = if j > 0 then memo_fib2 !! i !! (j - 1) else 0 +
if j > 1 then memo_fib2 !! i !! (j - 2) else 0 +
if i > 0 then memo_fib2 !! (i - 1) !! j else 0 +
if i > 1 then memo_fib2 !! (i - 2) !! j else 0
memo_fib2 = memo2D fib2
对于3-D,4-D等,我还必须输入相应的类和实例。 有没有办法在多维度函数上使这些优雅有效,这里是(Int-&gt; Int-&gt; ... - &gt; a)类函数的多维特征?
答案 0 :(得分:1)
如下所示。但是,在实践中,您可以从Hackage中选择一个现有的memoization库。
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
class Memo m a where
memo :: m -> a
instance Memo a a where
memo = id
instance (Memo m a) => Memo (Int -> m) [a] where
memo f = map (memo . f) [0..]
fib :: Int -> Int
fib 0 = 1
fib 1 = 1
fib n = memo_fib (n - 1) + memo_fib (n - 2)
memo_fib = (memo fib !!)
fib2 0 0 = 1
fib2 0 1 = 1
fib2 1 0 = 1
fib2 i j = sum . concat $ [ [ memo_fib2 i (j-1) | j > 0 ]
, [ memo_fib2 i (j-2) | j > 1 ]
, [ memo_fib2 (i-1) j | i > 0 ]
, [ memo_fib2 (i-2) j | i > 1 ]
]
memo_fib2 = let tab = memo fib2 in \x y -> tab !! x !! y