为了简单起见,我将使用以下虚构示例类(重点是我们有一些从方法派生出的昂贵数据):
当然,我们可以创建这个类的记忆化实现,例如:
但是,手动添加一个“因素”字段到每个将成为
这将需要大量的样板代码,将原始的所有其他操作从
class HasNumber a where
getNumber :: a -> Integer
getFactors :: a -> [Integer]
getFactors a = factor . getNumber
当然,我们可以创建这个类的记忆化实现,例如:
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
中。但是,有没有更优雅的解决方案呢?
getNumber
的结果是一些较大的数据结构,则这种方法会不太实用,并且(据我所知)这些条目永远不会被垃圾回收(与我的问题中的两个解决方案相反)。 - FunctorSalad