这是一个针对Haskell中的f1
函数(即斐波那契数列)的简单记忆化实现:
f1 = [calc n | n <- [0..]]
where calc 0 = 0
calc 1 = 1
calc n = f1 !! (n-1) + f1 !! (n-2)
现在,如果要为接受2个参数的函数f2或3个参数的函数f3实现这个功能,应该怎么做呢?
对于f2,最好的方法是使用列表嵌套列表吗?或者可以使用其他数据结构吗?
f2 = [[calc n m | n <- [0..]] | m <- [0..]]
where calc 0 0 = 0
calc a b = // ...something using (f2 !! a !! b)
对于
f3 a b c
,假设给定max_a * max_b * max_c
是可管理的,如何进行记忆化/动态规划?如果可能,我希望使用标准Haskell库来实现最简单/最直接的方法。
编辑
正如Chris Taylor所建议的,我尝试使用
MemoCombinators.hs
v0.5.1,但它对我失败了,就像这样:Could not find module `Data.IntTrie'
Use -v to see a list of the files searched for.
并且
Illegal symbol '.' in type
Perhaps you intended -XRankNTypes or similar flag
to enable explicit-forall syntax: forall <tvs>. <type>
我需要在“纯” Haskell 中运行此程序,使用版本为
GHCi,版本7.6.3
。有什么技巧可以让它运行?
type Memo
和memo2
,memo3
,这听起来对吗? - vikingstevedata-memocombinators
使用了两个扩展,Rank2Types 和 ScopedTypeVariables(包描述在此处)。如果您不想依赖使用扩展的软件包,则这可能不适合您。但是,您不需要在自己的模块中启用这些扩展,因此这可能对您是可接受的。 - Chris Taylordata-inttrie
库(它似乎是一种超级高效的位运算数据结构,也许我可以用Data.Map
做类似的事情?),然后使用type Memo
、wrap
、integral
和memo2
来实现我需要的自定义、“无外部库”的实现。 - vikingsteveData.Map
进行记忆化的经验是,对于具有两个以上参数的函数,很难使其正常工作,因为我无法让映射足够懒惰。但也许你会更幸运! - Chris Taylor