Remembering arguments independently

I have a simulation with a lot of function calls type F = A -> B -> C -> D , where A .. D are concrete types.

Type A objects have an average lifespan. (This is the codegolf ratrace genome .)

The most expensive calculation arises from parameter A I can easily remember this:

 f1 :: F f1 a = let expensive = trace "expensive computation!" $ expensiveComputation a in \bc -> expensive 

and hold some pre-processed expensive values ​​through a partial application:

 preProz :: [B -> C -> D] preProz = [f1 [], f1 [False], f2 []] 

Traces show that preProz <*> [[],[[]]] <*> [1,2] does not reflect the value in my delight.

Now I have learned that some of my F will also benefit from preprocessing B This preprocessing is independent of A , and, in fact, this memoirization has no advantage

 f2 a = let expensive = trace "expensive computation!" $ expensiveComputation a in \b -> let dear = trace "expensive computation!" $ expensiveComputation b in expensive + dear 

because dear recounted, even equal to B

I need something like:

 (B -> e) -> A -> e -> C -> D 

where e should be seen. Type e is conditional here. But this makes me recalculate all the values ​​of A for each B , which is just as bad, and I can not save e s, which are private to the function.

How can I memorize two parameters myself?

+6
source share
1 answer

You need a function that, together with memory a and b replaces:

 f12 ab = ... in \c -> ... 

If you want memoize a but not b , you use f1 a , and if you want memoize, you use f12 ab .

Of course, it would be nice to share some implementation between f1 and f12 . However, you can only do this if you have private functions that accept pre-calculated results instead of the original values:

 f1 a = privateA (precomputeA a) f12 ab = privateAB (precomputeA a) (precomputeB b) privateA a' b = privateAB a' (precomputeB b) private AB a' b' c = ... 

If the precompilation b depends on a preliminary calculation of a , then:

 f1 a = privateA (precomputeA a) f12 ab = let a' = precomputeA a in privateAB a' (precomputeB a' b) privateA a' b = privateAB a' (precomputeB a' b) private AB a' b' c = ... 

I intentionally did not use the composition function and this reduction to make things clearer. I also discarded any annotations of rigor that you might want to use to control the time of the assessment.

Memoizing may not be the right term here. You mean something like a β€œpartial app with some preliminary assessment.”

+1
source

Source: https://habr.com/ru/post/984100/


All Articles