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.
Related
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
1.
ghci> let x = trace "one" 1 in (x, x)
(one
1,one
1)
I expected let-expr would memorize x, so the result would look like:
(one
1,1)
2.
ghci> let !x = undefined in 1
...
error
...
Ok, strictly evaluated bang-pattern.
ghci> let !x = trace "one" 1 in 1
1
Because of the strictness I expected the result would look like:
one
1
You’ve been bitten by the fact that, since GHC 7.8.1, the monomorphism restriction is disabled in GHCi by default. This means that the x binding is generalized to a polymorphic, typeclass-constrained binding with the type
x :: Num a => a
since 1 is a polymorphic number literal. Even though this type does not include any function arrows (->), at runtime, it behaves more like a function than as a value, since it is really a function that accepts a Num typeclass dictionary and uses it to construct its result.
You can avoid this by explicitly annotating the literal to avoid the polymorphism:
ghci> let x = trace "one" (1 :: Integer) in (x, x)
(one
1,1)
ghci> let !x = trace "one" (1 :: Integer) in 1
one
1
Normally, the aforementioned monomorphism restriction is in place, precisely to prevent this kind of confusion where a binding that is syntactically a value definition can have its RHS evaluated multiple times. The linked answer describes some of the tradeoffs of the restriction, but if you want, you can switch it back on, which will make your original examples do what you expect:
ghci> :set -XMonomorphismRestriction
ghci> let x = trace "one" 1 in (x, x)
(one
1,1)
ghci> let !x = trace "one" 1 in 1
one
1
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 answers here:
Why is GHC complaining about non-exhaustive patterns?
(3 answers)
Closed 6 years ago.
The following is my factorial function:
factorial :: Integer -> Integer
factorial n
| n < 0 = -1
| n > 0 = n * factorial (n-1)
| n == 0 = 1
I guess, I covered all the cases (+ve, -ve, 0). When I try to load above code, I am getting following warnings. Why am I getting warnings?
Prelude> :load Fact.hs
[1 of 1] Compiling Main ( Fact.hs, interpreted )
Fact.hs:2:1: Warning:
Pattern match(es) are non-exhaustive
In an equation for ‘factorial’: Patterns not matched: _
Ok, modules loaded: Main.
This is ghc being conservative. Your code has all possible values of "n" covered, but ghc isn't smart enough to prove that, so it warns you.
Try replacing your "n < 0" with "otherwise" and putting it at the end. This is defined as
otherwise = True
That will become the catch-all case which will make ghc comfortable.
The compiler can't tell that all inputs match at least one of three guards.
Here's a suggestion to fix that and also remove some repetition:
factorial :: Integer -> Integer
factorial n = case compare n 0 of
LT -> -1
GT -> n * factorial (n-1)
EQ -> 1
I think the compiler isn’t smart enough to know that covering the three cases is exhaustive for the particular type. Simply use the otherwise pattern in the third rule instead of zero?
(And by the way, factorial is usually only defined for positive integers, so I don’t know how much your negative branch is correct.)
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]