Haskell basic factorial not exiting? [duplicate] - haskell

This question already has an answer here:
Infinite loop in haskell?
(1 answer)
Closed 9 years ago.
I'm learning Haskell, and am having trouble with a basic factorial function from this tutorial.
Basically, I've defined a factorial as such:
Prelude> let factorial 0 = 1
Prelude> let factorial n = n * factorial (n - 1)
The type checks out:
Prelude> :t factorial
factorial :: Num a => a -> a
which makes sense. However, the behavior of this function doesn't. It results in (interactive): out of memory no matter what the input is.
Prelude> factorial 5
(interactive): out of memory
I have to assume this is an infinite recursive call leading to an out of memory error, but I'm not sure what could possibly be causing it. The same thing happens with factorial 0, even though I've explicitly declared this to be 1:
Prelude> factorial 0
(interactive): out of memory
Now, here's the weird part: If I define the factorial function in a file, it works fine. I create a file tesths.hs s.t.:
factorial 0 = 1
factorial n = n * factorial (n - 1)
Then, if I go back to GHCI and run :l tesths.hs, I can execute factorial 5 without error.
What's going on here?

Two functions were defined, rather than a single function with two cases. Try the same commands having first run :set -Wall, and you should get a name shadowing warning. To solve the problem, try
let factorial 0 = 1; factorial n = n * factorial (n - 1)
instead.

You can also use the :{ ... :} syntax to give multi-line input:
Prelude> :{
Prelude| let factorial 0 = 1
Prelude| factorial n = n * factorial (n - 1)
Prelude| :}
Prelude> factorial 10
3628800
Prelude>
Similarly, you can use multiline mode and indentation with :set +m:
Prelude> :set +m
Prelude> let factorial 0 = 1
Prelude| factorial n = n * factorial (n - 1)
Prelude|
Prelude> factorial 10
3628800
Prelude>
Note the blank line. You can turn multiline mode back off with :unset +m.
See Section 2.4.3 of the GHC User's Guide, "[Using GHCi with] Multiline input" for documentation on this stuff.

Note that there is this pretty one-liner, too:
let factorial n = product [1..n]

Related

Stack overflow when defining Haskell Fibonacci

Just trying to do Exercise 3.7 (p. 31) of Hal Daumé III's YAHT manual, I tried to define the Fibonacci function:
fibo 1 = 1
fibo 2 = 1
fibo n = fibo(n-1) + fibo(n-2)
I then requested
fibo(3)
and got:
*** Exception: stack overflow
When I looked into the solution of the exercise I found exactly the same code (with the difference that the function is called fib instead of fibo). What am I doing wrong?
(The manual is from 2006, maybe the language has changed inbetween?)
(It is ironic that I ask stackoverflow for a problem of stack overflow…)
This is likely the result of defining the function in ghci one line at a time. This means that you first define a function fibo 1 = 1. Then you define another function with the name fibo (with fibo 2 = 2) that is scoped more locally, and finally you define a third function named fibo.
You can wrap multi-line functions between :{ and :}, and thus define one function fibo that consists out of three clauses:
Prelude> :{
Prelude| fibo 1 = 1
Prelude| fibo 2 = 1
Prelude| fibo n = fibo (n-1) + fibo (n-2)
Prelude| :}
Prelude> fibo 3
2

Deleting a function defined in GHCI

I'm starting to learn haskell and find myself having to restart the repl again and again because I defined incorrect specialization for a function and I don't know how to delete them.
For example, let's say I made the error of putting the base case of n == 0 after the general case for a factorial function:
fact n = n * fact(n-1)
fact 0 = 1
This is obviously wrong, now if I repeat the general case, it will be added to the current list, giving me 3 overloads for fact.
How do I delete the first case that I defined, or all the definitions of fact if possible. Is it possible to delete a function I defined in GHCI? If yes, how?
Prelude> fact n = n * fact (n-1)
Prelude> fact 0 = 1
Prelude> fact 3
*** Exception: <interactive>:6:1-10: Non-exhaustive patterns in function fact
Prelude> :q
Leaving GHCi.
bash> ghci
Prelude> fact 0 = 1
Prelude> fact n = n * fact (n-1)
Prelude> fact 3
*** Exception: stack overflow
What's going on?
With GHC, the first definition would result in a stack overflow, and the second one would be correct.
But in GHCi each binding shadows the previous one with the same name. In the example above, in each of the sessions each line that contains an equation for fact is a complete definition. When fact 3 is called, only the second line is in effect, and the first one is invisible.
So you cannot define functions the same way you do in normal GHC.
To define the factorial function correctly you can use one of these three methods.
A braced definition with no layout.
Prelude> let { fact 0 = 1; fact n = n * fact(n-1) }
A multiline definition with special GHCi braces.
Prelude> :{
Prelude| let fact 0 = 1
Prelude| fact n = n * fact (n-1)
Prelude| :}
A multiline definition with no special braces (needs :set +m which can be added to your ~/.ghci)
Prelude> let fact 0 = 1
Ptelude| fact n = n * fact (n-1)
Prelude|
Prelude>
See the manual for more imformation.
Note I have used let in these definitions, because I'm used to them, but they are in fact not necessary in newer versions of GHCi.

What is the multiple line in Haskell ? an operator , a function , something else?

I am very new to Haskell , and I must say I am puzzled
I am using GHCi prelude
First attemps to create a factorial
Prelude> factorial 0 = 1
Prelude> factorial n = n*factorial(n-1)
Prelude> factorial 2
*** Exception: stack overflow
ends up in stack overflow. Obviously recursion has not stopped.
Prelude> :t factorial
factorial :: Num t => t -> t
Then reading this post How to define a function in ghci across multiple lines?
I found out that I have to use either multiple line edition or braces (by the way is this an operator ?)
Prelude> let { fact 0 = 1 ; fact n = n * fact (n-1) }
Prelude> fact 5
120
Prelude> ::t fact
fact :: (Eq p, Num p) => p -> p
or
Prelude> :{
Prelude| facto 0 = 1
Prelude| facto n = n*facto(n-1)
Prelude| :}
Prelude> facto 4
24
Prelude> :t facto
facto :: (Eq p, Num p) => p -> p
So, my question is , why the first one is wrong, what happen in this case, why the 2nd and the 3rd are working, and from the result of the :t function, they seem to at least result in the exact same definition.
why the first one is wrong, what happen in this case
Because you defined two functions that had the same name.
First you define:
factorial 0 = 1
later you define:
factorial n = n*factorial(n-1)
But Haskell will see the second factorial as a variable that is scoped more local, so the second function definition, hides the previous one. The first line (factorial 0 = 1) is thus no longer part of the definition. Thus Haskell will evaluate factorial 2 -> 2 * factorial 1 -> 2 * 1 * factorial 0 -> 2 * 1 * 0 * factorial (-1) -> ....
why the 2nd and the 3rd are working
Because here you define a single function, and Haskell interpretets the two clauses as two clauses of the same function. The fact that with :t function you obtain the same, is just coincidence.
Note that the above only is valid for GHCi. If you work with a ghc compiler, it will of course see all your statements as part of the same function definition. In case you mix the clauses of two functions (e.g. first a 0 = 0, then b 0 = 0, and then a n = n) it will error about *multiple definitions for the same function).
In earlier versions of ghci, lines defining functions would have to be prepended with let. As of a recent version, the let is implicit in any definition line.
What this means is, each line defining your function is treated as its own let expression, so each subsequent line replaces (or 'shadows') the previous definition, instead of adding to it as would occur in a regular Haskell program.
The :{ and :} in ghci allow you to write several lines as a single input, whereas usually each line is treated independently in ghci. This means that you can write a multiline let expression:
:{
let fact 0 = 1
fact n = n * fact (n - 1)
:}
Or, in later versions, this is equivalent:
:{
fact 0 = 1
fact n = n * fact (n - 1)
:}
And the function fact will be defined as one would expect in a regular Haskell program.
When you define
Prelude> factorial 0 = 1
Prelude> factorial n = n*factorial(n-1)
Prelude> factorial 2
*** Exception: stack overflow
The first definition of factorial is discarded, so the function is defined as
Prelude> factorial n = n*factorial(n-1)
So you don't have a statement to end the recursion anymore.

Infinitely lazy factorial in Haskell

In a similar fashion as the Fibonacci series may be generated as follows,
fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
how to define the series for factorial.
Update
Embarrassingly enough, tried this quite before adding this question,
Prelude> let factorial = 2 : 6 : zipWith(*) factorial (tail factorial)
Prelude> take 5 factorial
[2,6,12,72,864]
Indeed the numbers in the tail are not successive values, to start with.
Lets take a step back and remember where that lazy version actually comes from:
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
We can also define the factorial similarly:
factorial 0 = 1
factorial n = factorial (n - 1) * n
As you can see, our zipping operation is actually (*), and the second list won't be a sublist of factorials, but instead [x..] with an appropriate x:
factorials = 1 : zipWith (*) factorials [x..]
What value should x be? Well, the second element should be 1 = 1 * 1, so it's 1, naturally:
factorials = 1 : zipWith (*) factorials [1..]
Note that we only need to give the first element, since we don't use tail or something similar. As you can see, your attempt was almost correct. You just used the wrong values for the left hand side:
Prelude> let factorial = 2 : 6 : zipWith (*) [4..] (tail factorial)
Prelude> take 10 $ factorial
[2,6,24,120,720,5040,40320,362880,3628800,39916800]
Remark: The factorial sequence is 0!, 1!, 2!, ..., so if you want to be OEIS compliant start with [1,1,...].
The idiomatic definition of a lazy list of factorials is not recursive at all: instead it uses the Prelude function scanl.
factorials = scanl (*) 1 [1..]
Given the usual definition of factorial:
factorial :: Integer -> Integer
factorial 0 = 1
factorial i = foldr (*) 1 [2..i]
we can generate an infinite list of all factorials by simply running the factorial function over an infinite list of all positive numbers:
inFact :: [Integer]
inFact = map factorial [0..]
Live demo

Haskell program crashing - infinite recursion? wrong where statement?

I need to calculate the product of all factorials from 1..n.
When I call this function double_factorial (with at least 2 or 3 as args),
it seems to be called for a moment, but nothing happens, and after a few seconds the GHCi just closes. What is wrong? Is there some infinite recursion that I can't see?
Here is my code :
double_factorial :: Integer->Integer
double_factorial n
| n<0 = error "negative number is given"
| n==0 = 1
| otherwise = (factorial n)*(double_factorial n-1)
where
factorial :: Integer->Integer
factorial n
| n == 0 = 1
| otherwise = n*(factorial n-1)
(double_factorial n-1) means ((double_factorial n) - 1) so yes, it's an infinite recursion problem.
First off, because you opened GHCi directly, the terminal window in which it is running closes as soon as GHCi stops running. If you open up cmd (or similar terminal) and then use GHCi from there, you can see the error that GHCi throws as it stops running. In this case we get:
<interactive>: out of memory
This does suggest an infinite recursion problem, as you already suspected.
Because factorial is the simpler function, it's easier to check if its recursive call is the culprit. It is, as factorial n - 1 means (factorial n) - 1 and not factorial (n - 1). And calling factorial n in the definition of factorial n is pretty much the textbook case of infinite recursion. In double_factorial we see the same problem.
You have a recursion problem: f x - 1 is not the same as f (x - 1). Solution (removing unneeded parentheses and adding the needed ones):
double_factorial :: Integer->Integer
double_factorial n
| n<0 = error "negative number is given"
| n==0 = 1
| otherwise = factorial n * double_factorial (n-1)
where
factorial :: Integer->Integer
factorial n
| n == 0 = 1
| otherwise = n * factorial (n-1)

Resources