存储“常量”而不用在Haskell中重新评估它们
我正在修补一个评估最佳 yahtzee 游戏的程序。经常需要做的事情是为每个可能的滚动执行给定的任务。以下函数创建一个列表,其中包含所有可能的滚动条,这些滚动条将被频繁映射。
type Roll = [Int]
rollspace :: Int -> [Roll]
rollspace depth = worker [[]] 0
where m xs n = map (e -> n:e) xs
addRoll xs = m xs 1 ++ m xs 2 ++ m xs 3 ++ m xs 4 ++ m xs 5 ++ m xs 6
worker xs i = if i == depth then xs else worker (addRoll xs) (i+1)
此函数按预期工作,并在使用depthof运行时生成 7776 个项目的列表5。然而,在任何需要的时候生成给定深度的所有滚动列表似乎效率很低,特别是因为深度只会在范围内1-5。有没有办法存储rollspace所需深度的列表并在不重新评估的情况下引用它们,或者 Haskell 是否编译了这个问题?
回答
有没有办法存储所需深度的滚动空间列表并在不重新评估的情况下引用它们?
是的,当然,它甚至是您已经知道的技术。
rollspace5 :: [Roll]
rollspace5 = rollspace 5
rollspace4 :: [Roll]
rollspace4 = rollspace 4
-- etc.
如果您有一个接受数字作为输入的“类函数”对象很重要——即,而不是静态地知道您想要深度 5——您有几个选择,包括:
rollspaceStored :: Int -> [Roll]
rollspaceStored 5 = rollspace5
rollspaceStored 4 = rollspace4
-- etc.
rollspaceStored other = rollspace other
rollspaceMap :: IntMap [Roll]
rollspaceMap = fromList [(n, rollspace n) | n <- [0..5]]
Hackage 上也有一些更普遍的记忆包;该搜索词应该足以找到它们。