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
Related
I have been trying to implement a list of Fibonacci number sequence from 0 to n without using the lazy zipwith method. What I have so far is code that returns a list from n to 1. Is there any way I can change this code so it returns the list from 0-n at all?
Example:
fib_seq 4 = [3,2,1,1]
-- output wanted: [1,1,2,3]
If there is not a way to do what I want the code to do, is there a way to just return the list of Fibonacci numbers taking in a number say again 4 it would return [0, 1, 1, 2].
fib_seq :: Int -> [Int]
fib_seq 0 = [0]
fib_seq 1 = [1]
fib_seq n = sum (take 2 (fib_seq (n-1))) : fib_seq (n-1)
Another way you could choose to implement the fib numbers is the use of a helper function then a function on it's own that will produce the infinite list of fib numbers, or you could use take 10 fibs and the output for this would be the first 10 fib numbers. My function is definitely not the fastest way to work out the fib numbers infintely that would be with the zipWith function, but you are not using that here so here is my way to implement it without zipWith.
for example take 10 fibs would return: [0,1,1,2,3,5,8,13,21,34]
fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
fibs :: [Int]
fibs = (map fib [0..])
It is often the case that you can solve a problem by considering a slightly more general version of it.
Say we want the infinite Fibonacci list starting with two prescribed initial values a and b. There is an obvious recursive solution:
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
...
λ>
λ> aux_fib a b = a : (aux_fib b (a+b))
λ>
λ> take 4 (aux_fib 1 1)
[1,1,2,3]
λ>
And so:
λ>
λ> fib_seq n = take n (aux_fib 1 1)
λ>
λ> fib_seq 4
[1,1,2,3]
λ>
Note: camel case is regarded as more idiomatic in Haskell, so it would be more like auxFib and fibSeq.
If you wanted to have the list start from 0 you could use a helper function and then use this helper function within your fib_seq (which i recommend you change to Camel case so like fibSeq, standard haskell notation)
Ok so the functions as follow fibSeq 7 would return [0,1,1,2,3,5,8]:
fibHelp :: Int -> Int -> [Int]
fibHelp x y = x : (fibHelp y (x+y))
fibSeq :: Int -> [Int]
fibSeq n = take n (fibHelp 0 1)
It feels a bit like cheating, but you could use the closed formula for the Fibonacci sequence like this:
fib n = (phi^n - psi^n) / sqrt 5
where
phi = (1 + sqrt 5) / 2
psi = (1 - sqrt 5) / 2
fibSeq n = fib <$> [1 .. n]
Otherwise the Haskell Wiki has many more implementation variants to chose from. For example very succinctly
fibs = 0 : 1 : next fibs
where
next (a : t#(b:_)) = (a+b) : next t
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.
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.
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]
I have come up with the following tail-recursive fibonacci generator that works:
let {
fibo :: Integral x => [x]->x->x->x->[x]
fibo l x y 0 = l
fibo l x y n = fibo (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
}
Pardon me for the whole implementation put in one line because i am using the GHCi and haven't quite learnt how to put this in a file and run (i am yet to reach there). What i want to know is how this call:
fibo [0, 1] 0 1 5
can be improved. I do not want to pass the initial list with 0 and 1 and then pass 0 and 1 again with the limit. I believe that the implementation can be changed. What changes can be done?
Your algorithm is tail-recursive, but it looks like it has other drawbacks, namely 1) you are building the result list by appending to the end of it, and 2) it's not lazy.
For 1), note that when you append two lists a ++ b, you essentially have to reallocate a. In your case a is the growing list of fibonacci numbers and b are the next two terms. So each iteration reallocates the fibonacci numbers that have already been computed and adds on two more elements which will result in quadratic running time. It would be more efficient to prepend b to the front of a. You'll be producing the fibonacci numbers in reverse, but the running time will be linear. You can then reverse the list at the end if you want the sequence in ascending order.
Note that building the list in reverse order allows you to easily get at the last two terms of the sequence by using Code-Guru's pattern-matching idea.
For 2), note that you can't get the first element of the list until the entire computation has completed. Compare with the following lazy generation of the sequence:
fibs = 0 : (go 0 1)
where go a b = b : go b (a+b)
Even though it looks like the recursion never stops, fibs is only evaluated for as much as is needed. For example, fibs !! 3 only calls go a couple of times.
I'm not going to go to the algorithm itself, but here's some advice on how to structure your recursive functions.
First, here's how you would format your code in a separate file
fibo :: Integral x => [x]->x->x->x->[x]
fibo l x y 0 = l
fibo l x y n = fibo (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
If you save this as fibo.hs, then you can start GHCi with
ghci fibo.hs
to load the file at start. You can also load the file after starting GHCi with the command
:l fibo.hs
(assumming you start GHCi in the same directory where you saved fibo.hs)
Another nice feature is that now when you edit the file, you can reload all your changes by simply entering
:r
in the GHCi prompt.
Now, to get rid of the extra parameters, the usual pattern in Haskell is to refactor the recursive part to its own helper function and have the main function as an entry point that only takes the necessary parameters. For example,
fibo :: Integral x => x -> [x]
fibo n = fiboHelper [0,1] 0 1 n
fiboHelper :: Integral x => [x]->x->x->x->[x]
fiboHelper l x y 0 = l
fiboHelper l x y n = fiboHelper (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
Now you can call fibo simply with
> fibo 3
[0,1,1,2,3,5,8,13]
Also, a helper function like this that is not useful by itself is usually hidden inside the main function as an inner function using let or where.
fibo :: Integral x => x -> [x]
fibo n = fiboHelper [0,1] 0 1 n where
fiboHelper l x y 0 = l
fiboHelper l x y n = fiboHelper (l ++ [y+x] ++ [y+x+y]) (x+y) (y+x+y) (n-1)
An inner function like this is usually given a shorter name, because the context makes its purpose clear, so we could change the name to e.g. fibo'.
go is another commonly used name for a recursive helper function.
Just for the record: The "usual" definition for a list of Fibonacci numbers is:
fibo = 0 : scanl (+) 1 fibo