I’m writing my first program with effects about memoization. The idea is that a recursive function sends and effect asking about all arguments that has been passed to it in the current call stack and gets this list as effect result. Than it does some useful work wrapped into
try block which handles the same effect and returns the previous list extended with current call arguments.
And it seems that second raising of the effect is not handled. I want to know how to understand why this is happening in general case. Below is the part of relevant code and a link to the full repo. It should be compilable but I hope that it s not needed.
➜ ocanren-eff git:(eff) ✗ ./test666.native Entering appendo '[1; 2; 3]' and '[4; 5]' and '_.10' handlig askAppendo regression/test666.ml 58 Size of cache is 1 Entering appendo '[2; 3]' and '[4; 5]' and '_.13' Fatal error: exception Unhandled
A piece of relevant code:
17 effect AskAppendoCache : (Obj.t * Obj.t * Obj.t) -> Cache3.t 20 let rec appendo a b ab = fun st -> 21 let _ = ignore @@ project3 ~msg:"Entering appendo" a b ab st in 22 let cache = perform (AskAppendoCache Obj.(repr a, repr b, repr ab)) in 23 let () = printf "Size of cache is %d\n%!" (Cache3.size cache) in 24 25 let inner st0 = conde 26 [ ((a === nil ()) &&& (b === ab)) 27 ; Fresh.three @@ fun h t ab' -> 28 ?& [ 29 (a === h%t); 30 (h%ab' === ab); 31 (appendo t b ab'); 32 ] 33 ] st0 34 in 35 match inner st with 36 | x -> x 37 | effect (AskAppendoCache new_arg) k -> 38 continue k Cache3.(extend new_arg cache) 52 let () = 53 runL (-1) q qh ("", (fun q -> fun st -> 54 let rel st = appendo (ilist [1;2;3]) (ilist [4;5]) q st in 56 match rel st with 57 | effect (AskAppendoCache arg) k -> 58 printf "handlig askAppendo %s %d\n" __FILE__ __LINE__; 59 continue k Cache3.(extend arg empty) 60 | effect (AskReversoCache arg) k -> 61 printf "handlig askReverso\n"; 62 continue k Cache3.(extend arg empty) 63 | stream -> stream 64 )); 65 () 66
@kayceesrk, please, rescue me