-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Recursion #1
Comments
That's a good idea to explore The elm equivalent of the purescript library you mention is trampoline. I believe that this replicateM implementation is equivalent to yours replicateM : Int -> State s a -> State s (List a)
replicateM n s =
let
go ( n, xs ) =
if n <= 0 then
done xs
else
jump (\_ -> go ( n - 1, map2 (::) s xs ))
in
go ( n, state [] )
|> evaluate This implementation doesn't need helpers in the library: only the user can do the For testing/documentation purposes, do you have a concrete concise example that |
Unfortunately trampoline doesn't help in this case > finalState 0 (replicateM 1000 (state 3))
0 : number
> finalState 0 (replicateM 5000 (state 3))
0 : number
> finalState 0 (replicateM 10000 (state 3))
RangeError: Maximum call stack size exceeded Similarly for > finalState 0 (traverse put [1..1000])
1000 : number
> finalState 0 (traverse put [1..5000])
5000 : number
> finalState 0 (traverse put [1..10000])
RangeError: Maximum call stack size exceeded And after reimplementing > finalState 0 (traverseRec put [1..1000])
1000 : number
> finalState 0 (traverseRec put [1..5000])
5000 : number
> finalState 0 (traverseRec put [1..10000])
10000 : number
> finalState 0 (traverseRec put [1..100000])
100000 : number
> finalState 0 (traverseRec put [1..1000000])
1000000 : number
> finalState 0 (traverseRec put [1..10000000])
-- Some time later
10000000 : number
> finalState 0 (traverseRec put [1..100000000000])
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [/usr/bin/node]
2: 0xd6acec [/usr/bin/node]
3: v8::Utils::ReportApiFailure(char const*, char const*) [/usr/bin/node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/bin/node]
5: v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/usr/bin/node]
6: v8::internal::Runtime_AllocateInTargetSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/bin/node]
7: 0x3945b4079a7 We need a stack safe function that knows about into the internals of |
Well, that's interesting. I intend to look at this in more detail tomorrow/later, some things I hope to find out
|
I've introduced the stack-safe functions in a branch As you said, the reason trampoline/list folds don't solve the stack problem is that they don't I have however included the examples/Euler14 which still overflowing the stack (for upper > 500_000)
Here, So, does this solve your problems? |
As you point out in the readme: https://github.com/folkertdev/elm-state#problems this is not stack-safe. How would you feel about taking inspiration from purescript-tailrec and adding something like
tailRecM
specifically for this case?With it you can implement stack safe recursive functions like
replicateM
:The text was updated successfully, but these errors were encountered: