【发布时间】:2011-12-13 06:13:59
【问题描述】:
为了简单起见,我将使用这个人为的示例类(关键是我们有一些从方法派生的昂贵数据):
class HasNumber a where
getNumber :: a -> Integer
getFactors :: a -> [Integer]
getFactors a = factor . getNumber
当然,我们可以做这个类的memoizing实现,比如:
data Foo = Foo {
fooName :: String,
fooNumber :: Integer,
fooFactors :: [Integer]
}
foo :: String -> Integer -> Foo
foo a n = Foo a n (factor n)
instance HasNumber Foo where
getNumber = fooNumber
getFactors = fooFactors
但要求手动将“因素”字段添加到任何将成为HasNumber 实例的记录似乎有点难看。下一个想法:
data WithFactorMemo a = WithFactorMemo {
unWfm :: a,
wfmFactors :: [Integer]
}
withFactorMemo :: HasNumber a => a -> WithFactorMemo a
withFactorMemo a = WithFactorMemo a (getFactors a)
instance HasNumber a => HasNumber (WithFactorMemo a) where
getNumber = getNumber . unWfm
getFactors = wfmFactors
不过,这将需要大量样板来将原始 a 的所有其他操作提升到 WithFactorMemo a。
有什么优雅的解决方案吗?
【问题讨论】:
-
我刚刚想到的另一个解决方案是让 factor 函数记忆,尽管如果
getNumber的结果是一些更大的数据结构,这将不太实用,并且(AFAIK)条目永远不会被垃圾收集(与我的问题中的两个解决方案相反)。
标签: haskell memoization