Haskell 中的两个参数记忆
我正在尝试记住以下函数:
gridwalk x y
| x == 0 = 1
| y == 0 = 1
| otherwise = (gridwalk (x - 1) y) + (gridwalk x (y - 1))
看着 this 我想出了以下解决方案
gw :: (Int -> Int -> Int) -> Int -> Int -> Int
gw f x y
| x == 0 = 1
| y == 0 = 1
| otherwise = (f (x - 1) y) + (f x (y - 1))
gwlist :: [Int]
gwlist = map (\i -> gw fastgw (i `mod` 20) (i `div` 20)) [0..]
fastgw :: Int -> Int -> Int
fastgw x y = gwlist !! (x + y * 20)
:然后我可以这样调用:
gw fastgw 20 20
是否有一种更简单、更简洁和通用的方法(注意我如何必须在 gwlist 函数中对最大网格尺寸进行硬编码,以便从 2D 空间转换为 1D 空间,所以我可以访问记忆列表)来记忆Haskell中具有多个参数的函数吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以使用列表的列表来记住两个参数的函数结果:
You can use a list of lists to memoize the function result for both parameters:
使用 hackage 中的 data-memocombinators 包。它提供了易于使用的记忆技巧,并提供了一种简单而简洁的使用方式:
Use the data-memocombinators package from hackage. It provides easy to use memorization techniques and provides an easy and breve way to use them:
这是使用 MemoTrie 包中的
Data.MemoTrie
的版本记住函数:Here is a version using
Data.MemoTrie
from the MemoTrie package to memoize the function:如果你想要最大程度的通用性,你可以记忆一个记忆函数。
该技术适用于具有任意数量参数的函数。
编辑:感谢 Philip K. 指出原始代码中的错误。最初,memo 有一个“Bounded”约束而不是“Num”,并从
minBound
开始枚举,这仅对自然数有效。不过,列表并不是一种很好的记忆数据结构,因为它们具有线性查找复杂性。使用 Map 或 IntMap 可能会更好。或者查看 黑客。
请注意,此特定代码确实依赖于惰性,因此如果您想切换到使用 Map,则需要从列表中获取有限数量的元素,如下所示:
我认为 ghc 在这种情况下共享可能很愚蠢,您可能需要取出
x
和y
参数,如下所示:If you want maximum generality, you can memoize a memoizing function.
This technique will work with functions that have any number of arguments.
Edit: thanks to Philip K. for pointing out a bug in the original code. Originally
memo
had a "Bounded" constraint instead of "Num" and began the enumeration atminBound
, which would only be valid for natural numbers.Lists aren't a good data structure for memoizing, though, because they have linear lookup complexity. You might be better off with a Map or IntMap. Or look on Hackage.
Note that this particular code does rely on laziness, so if you wanted to switch to using a Map you would need to take a bounded amount of elements from the list, as in:
I think ghc may be stupid about sharing in this case, you may need to lift out the
x
andy
parameters, like this: