Ho una simulazione con molte chiamate alle funzioni dello type F = A -> B -> C -> D
, dove A
.. D
sono tipi concreti.Memoizzazione indipendente degli argomenti
Gli oggetti del tipo A
hanno una durata media. (È il genoma di codegolf's ratrace.)
Il calcolo più costoso deriva dal parametro A
. Posso facilmente Memoize simili:
f1 :: F
f1 a = let expensive = trace "expensive computation!" $ expensiveComputation a
in \b c -> expensive
premuto alcuni expensive
valori pre-elaborati tramite applicazione parziale:
preProz :: [B -> C -> D]
preProz = [f1 [], f1 [False], f2 []]
Le tracce indicano che preProz <*> [[],[[]]] <*> [1,2]
non ricalcola i valori per la mia gioia.
Ora ho scoperto che alcuni dei miei F
s trarrebbero vantaggio dalla pre-elaborazione B
, anche. Questa pre-elaborazione è indipendente da A
, e, infatti, memoizing simili ha alcun beneficio
f2 a = let expensive = trace "expensive computation!" $ expensiveComputation a
in \b -> let dear = trace "expensive computation!" $ expensiveComputation b
in expensive + dear
perché dear
viene ricalcolato, anche la b
s uguali.
Che cosa ho bisogno è qualcosa di simile:
(B -> e) -> A -> e -> C -> D
dove dovrebbe essere memoized e
. Il tipo di e
è in ordine di sorta qui. Ma questo mi costringe a ricalcolare tutti i valori A
per ogni B
, che è altrettanto grave, e non posso salvare i e
s, che sono privati della funzione.
Come posso memoize lungo 2 parametri in modo indipendente?
La preelaborazione di A dipende da B o viceversa? Se la pre-elaborazione non dipende da altri argomenti, perché non spostarla semplicemente dalla funzione: 'f1 <$> [procA a1, procA a2] <*> [procB b1, procB b2] <*> ...' Ora è garantita la pre-elaborazione solo una volta per ogni argomento. –
Intendo "sposta fuori dalla funzione". –
"non ricalcolare i valori è [come?] Inteso" è un fraseggio ambiguo: potrebbe anche significare "Mi aspettavo che lo ricalcasse, e non lo ha fatto" – chi