What are the usual causes of "Error C stack overflow" in the Hugs Haskell implementation.
相关问题
- Understanding do notation for simple Reader monad:
- Making Custom Instances of PersistBackend
- Haskell: What is the differrence between `Num [a]
- applying a list to an entered function to check fo
- How can I increase the maximum call stack size in
相关文章
- Is it possible to write pattern-matched functions
- Haskell underscore vs. explicit variable
- Top-level expression evaluation at compile time
- Stuck in the State Monad
- foldr vs foldr1 usage in Haskell
- List of checkboxes with digestive-functors
- How does this list comprehension over the inits of
- Replacing => in place of -> in function type signa
A runaway recursion is the most likely candidate... You need to give more info though for a more precise answer.
Here's some code that could cause a runaway recursion:
What happens here is that when
x
is evaluated inprint x
it starts, then finds out that to complete its evaluation it needs to evaluatex
.This can come up if you are used to functional languages in which it is common to do tail-recursion factorization. Say you have a function:
Which, incidentally, is the same as
If we evaluate the function we can see the problem:
Now to evaluate that expression Haskell uses a stack:
And this is where an overflow can occur. If you evaluated sum [1..10^6], that stack would be a million entries deep.
But note the pathology here. You recurse over a list only to build up a huge fscking expression ("thunk"), and then use a stack to evaluate it. We would rather evaluate it as we are recursing, by making the tail recursion strict:
That says to evaluate accum before trying to evaluate the recursive call, so we get (this may take a some patience to understand):
So as we are traversing the list, we are computing the sum so we don't have to use a deep stack to evaluate the result. This modified tail recursion pattern is encapsulated in Data.List.foldl', so:
A good rule of thumb is to never use foldl, because it always builds up giant thunks. Use foldl' instead. If the output type has lazy structure (eg. a list or a function), use foldr. But there is no silver bullet for avoiding a stack overflow in general, you just have to understand the evaluation behavior of your program. This can be hard sometimes.
But, if I understand correctly, a stack overflow always comes from trying to evaluate a gigantic thunk, though. So look for places where those could be created, and force evaluation to happen earlier.
The most likely cause has to be uncontrolled recursion. Each recursive call consumes a little more stack space for its input/ouput parameters.