Để giữ cho nó đơn giản, tôi sẽ sử dụng lớp ví dụ contrived này (Vấn đề là chúng ta có một số dữ liệu đắt tiền có nguồn gốc từ phương pháp):Memoization và typeclasses
class HasNumber a where
getNumber :: a -> Integer
getFactors :: a -> [Integer]
getFactors a = factor . getNumber
Tất nhiên, chúng ta có thể làm cho việc triển khai memoizing của lớp này như:
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
Nhưng nó có vẻ hơi xấu xí để được yêu cầu tự thêm một lĩnh vực 'yếu tố' đến bất cứ hồ sơ đó sẽ là một ví dụ HasNumber
. Ý tưởng tiếp theo:
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
này sẽ đòi hỏi rất nhiều soạn sẵn để nâng tất cả các hoạt động khác của bản gốc a
vào WithFactorMemo a
, mặc dù.
Có giải pháp thanh lịch nào không?
Một giải pháp khác mà tôi cho là sẽ làm cho chức năng * yếu tố * ghi nhớ, mặc dù điều này sẽ ít thực tế hơn nếu kết quả của 'getNumber' là cấu trúc dữ liệu lớn hơn, và (AFAIK) (trái ngược với hai giải pháp trong câu hỏi của tôi). – FunctorSalad