Mam symulację z mnóstwem wywołań funkcji type F = A -> B -> C -> D
, gdzie A
.. D
są konkretne typy. Obiekty o typie A
mają średni czas życia. (To jest genom codegolf's ratrace.)Niezależne od siebie argumenty
Najdroższe obliczenia wynikają z parametru A
. Mogę łatwo memoize tak:
f1 :: F
f1 a = let expensive = trace "expensive computation!" $ expensiveComputation a
in \b c -> expensive
i przytrzymać kilka wstępnie przetworzonych expensive
wartości poprzez częściowego zastosowania:
preProz :: [B -> C -> D]
preProz = [f1 [], f1 [False], f2 []]
Ślady wskazują, że preProz <*> [[],[[]]] <*> [1,2]
nie przeliczyć wartości do mojego zachwytu.
Teraz dowiedziałem się, że niektóre z moich F
s również skorzystają z wstępnego przetwarzania B
. To wstępne przetwarzanie jest niezależny z A
, aw rzeczywistości memoizing jak to ma korzyści
f2 a = let expensive = trace "expensive computation!" $ expensiveComputation a
in \b -> let dear = trace "expensive computation!" $ expensiveComputation b
in expensive + dear
ponieważ dear
jest wyliczany, nawet jest b
s równe.
Co potrzebne jest coś takiego:
(B -> e) -> A -> e -> C -> D
gdzie e
należy memoized. Typ e
jest tutaj w pewnym sensie egzystencjalnym. Ale to zmusza mnie do przeliczenia wszystkich wartości A
dla każdego B
, który jest tak samo zły i nie mogę zapisać e
s, które są prywatne dla funkcji.
Jak mogę niezależnie zapamiętać 2 parametry?
Czy wstępne przetwarzanie A zależy od B lub odwrotnie? Jeśli wstępne przetwarzanie nie zależy od innych argumentów, to dlaczego nie po prostu przenieść go z funkcji: 'f1 <$> [procA a1, procA a2] <*> [procB b1, procB b2] <*> ...' Teraz wstępne przetwarzanie jest gwarantowane do uruchomienia tylko raz dla każdego argumentu. –
Mam na myśli "przenieś go z funkcji". –
"nie oblicza ponownie wartości jest [jak?] Przeznaczony" jest niejednoznacznym sformułowaniem: może to również oznaczać "Oczekiwano, że to się wyrejestruje, a nie" – chi