Haskell: What is wrong with factorial function [duplicate] - haskell

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.)

Related

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.

List comprehension and type problems (Haskell)

I have annoying syntax error in following construction:
isPrime n = if numOfDivisors n == 0 then True else False
where numOfDivisors n = length $ [x | x <- [2..ceiling (sqrt n)], n `mod` x == 0]
How I can fix it? I'm new to Haskell, so I don't know what's wrong in [2..ceiling (sqrt n)].
Thanks (sorry for my poor brain).
You're using both sqrt and mod with n--the first requires a floating point type, the latter requires an integral type. You probably want the latter, and to use sqrt (fromIntegral n) instead.
Some other unsolicited advice:
There is no possible reason to do if foo then True else False. Just use the boolean expression alone.
Function arguments are in scope in the where clause, so numOfDivisors doesdn't need n as an argument.
Don't use length to check if a list is empty. Use null on the list of divisors instead.

Haskell "No instance for" type error in simple code

I am a really big noob to Haskell.
I have this code:
4 sieve n i = if i < n
5 then
6 do {
7 innerSieve n;
8 sieve n (i + 1);
9 }
10 else -1
11
12 innerSieve n = return n
13
14 --innerSieve n i j = [x | x <- [i..n], x `mod` j == 0]
and I have this error:
[1 of 1] Compiling Main ( sieve.hs, interpreted )
Ok, modules loaded: Main.
*Main> sieve 10 2
<interactive>:1:1:
No instance for (Num (m0 b0))
arising from a use of `sieve'
Possible fix: add an instance declaration for (Num (m0 b0))
In the expression: sieve 10 2
In an equation for `it': it = sieve 10 2
*Main>
I've been banging my head against a wall trying to understand what it means by "No instance for (Num (m0 b0))." What in the world is a m0 b0?
I thought this might help:
*Main> :t sieve
sieve :: (Ord a, Num a, Num (m b), Monad m) => a -> a -> m b
*Main>
EDIT:
I am trying to recreate the sieve of erastothenes by making a recursive function with a list comprehension, basically. I also want to -understand- everything in the code.
Your inner do block has a monadic type. This makes the entire result of sieve have a monadic type of (Monad m) => m b. The else branch of your if statement returns -1, so we know it also has a numeric type. This makes the result of your function (Num (m b), Monad m) => m b. This is very clearly wrong.
I can't figure out what your function is trying to accomplish, so I'm not sure where exactly you went wrong. I would recommend writing explicit type annotations on your functions, to express exactly what you're expecting each function to do. That will, at a minimum, give you better error messages, because instead of saying that the inferred type doesn't make sense, it can point you to exactly what expression doesn't match the explicit type.
BTW, you might find the if statement is better expressed as
sieve n i
| i < n = -- contents of the then block
| otherwise = -1
Haskell is a functional language. This especially means, that you don't tell the compiler Do A then do B but rather calculate A – You don't tell the compiler in what order to do things, rather you tell it what you want to know. You can think of that as having only one (return) statement. Thus, you need to rewrite your code to fit to this paradigma.
The do statement is for a special construct called monad that essentially allows stateful actions (such as printing to the screen) in a consistent manners. You don't need it.
As the others already showed you, you can do something like this. The pipe (|) is called pattern guard and essentially works like an If-then-else:
sieve n i | i < n = --result if condition is met
| otherwise = -1
Remember that you can't change the values of variables. You may need to rewrite your innerSieve to return something.
As others have said, you almost certainly dont want to use a do block in your code where you do. do is for Monads and should be avoided when learning Haskell, and is probably inappropriate since the only Monad here is [] which would ignore any definition of innerSieve. Haskell code describes values and types in terms of other values and types. Haskell programs dont tell the computer what to do, they tell it what is. This is a radical way of thinking, but a very powerful one. do notation is a special syntax for handling monads which are a special kind of value that can be used to encode computations (including imperative computations and state transitions) cleanly and efficiently, but it requires a broad understanding of Haskell to use well.
My advice to Haskell newbies is "Avoid monads and do notation until you have mastered: recursion, higher order functions, and typeclasses. You dont need do to test your programs (use GHCi), so learn the real functional way of thinking. Try to program such that your programs dont do anything!"
So, how would you go about writing a sieve of Eratosthenes in Haskell? There are many elegant ways. Warning: spoilers ahead. If you want to do this by yourself stop reading
You have commented out:
innerSieve n i j = [x | x <- [i..n], x `mod` j == 0]
I'm not sure what the point of n and i are here. It would be more elegant to write
innerSieve j ls = [x | x <- ls, x `mod` j == 0]
which has the type
innerSieve :: Integral x => x -> [x] -> [x]
so, in other words, it takes a list a value of some type x such that that type can be treated like an integer, and returns all the integral multiples of the original value.
You could use this to write the sieve of Eratosthenes, but a better way would be to get all the values that are not multiples. The reason is that, then you can just stack a bunch of these together to produce your full prime sieve
innerSieve j ls = [x | x <- ls, x `mod` j /= 0]
Here the /= is Haskell's way of saying "not equal". Cool, so lets build a prime sieve out of this
sieve (x:xs) = x : sieve (innerSieve x xs)
sieve [] = []
What does this say? well it takes a list of numbers, and gives you back a new list consisting of the first of those numbers, and the sieve applied to the rest of those numbers except for those that are multiples of the first one. The (x:xs) is a pattern that matches any list other than the empty list, binding x with the head of the list, and xs with the tail of the list. [] is a pattern that matches any empty list.
Finally, you can define the infinite list of all primes
primes = sieve [2..]
The expression [2..] generates the list 2,3,4,5,6,7,etc going on forever. Looks scary (infinite lists), but is okay because of Haskell's famed lazy evaluation. To get the nth prime you can say:
nthPrime n = primes !! (n - 1)
which just indexes into the list of primes. Haskell will only compute the minimum needed to return the result, so this function will terminate even though primes is infinitely long
or to get all the primes up to a number
primesUpToN n = take n primes
so, your entire code base ends up being:
sieve [] = []
sieve (x:xs) = x : sieve (innerSieve x xs) where
innerSieve j ls = [x | x <- ls, x `mod` j /= 0]
primes = sieve [2..]
nthPrime n = primes !! (n - 1)
primesUpToN n = take n primes
This isn't really the sieve of Eratosthenes, since you aren't "marking off" values. But, this sieve is actually "better" insofar as it is both faster and defines the set of all primes, rather than those up to a number. It is not how you should ever actually go about generating primes, but in 6 lines of code (most of which are unnecessary), it is hard to argue that mutation or looping makes things simpler.
Not only does this give a type error:
do {
innerSieve n;
sieve n (i + 1);
}
But it has the exact same value as
do {
sieve n (i + 1);
}
You have called a function "innerSeive", but then not done anything with the value.
If you would like to compute a value and then use the value in the next operation, use the (>>=) operator (sugared as let x = innerseive n; f2 n; within a do block).
However, for these mathematical functions, stay far, far away from do, let, (>>=), etc.

Project euler problem 3 in haskell

I'm new in Haskell and try to solve 3 problem from http://projecteuler.net/.
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
My solution:
import Data.List
getD :: Int -> Int
getD x =
-- find deviders
let deriveList = filter (\y -> (x `mod` y) == 0) [1 .. x]
filteredList = filter isSimpleNumber deriveList
in maximum filteredList
-- Check is nmber simple
isSimpleNumber :: Int -> Bool
isSimpleNumber x = let deriveList = map (\y -> (x `mod` y)) [1 .. x]
filterLength = length ( filter (\z -> z == 0) deriveList)
in
case filterLength of
2 -> True
_ -> False
I try to run for example:
getD 13195
> 29
But when i try:
getD 600851475143
I get error Exception: Prelude.maximum: empty list Why?
Thank you #Barry Brown, I think i must use:
getD :: Integer -> Integer
But i get error:
Couldn't match expected type `Int' with actual type `Integer'
Expected type: [Int]
Actual type: [Integer]
In the second argument of `filter', namely `deriveList'
In the expression: filter isSimpleNumber deriveList
Thank you.
Your type signature limits the integer values to about 2^29. Try changing Int to Integer.
Edit:
I see that you already realised that you need to use Integer instead of Int. You need to change the types of both getD and isSimpleNumber otherwise you will get a type mismatch.
Also in general, if you are having trouble with types, simply remove the type declarations and let Haskell tell you the correct types.
Main> :t getD
getD :: Integral a => a -> a
Main> :t isSimpleNumber
isSimpleNumber :: Integral a => a -> Bool
After you found the error, may I point out that your solution is quite verbose? In this case a very simple implementation using brute force is good enough:
getD n = getD' n 2 where
getD' n f | n == f = f
| n `mod` f == 0 = getD' (n `div` f) f
| otherwise = getD' n (succ f)
this question is easy enough for brute-force solution, but it is a bad idea to do so because the whole idea of project euler is problems you need to really think of to solve (see end of answer)
so here are some of your program's flaws:
first, use rem instead of mod. it is more efficient.
some mathematical thinking should have told you that you don't need to check all numbers from 1 to x in the isprime function and the getD function, but checking all numbers from the squareroot to one (or reversed) should be sufficient. note that in getD you will actually need to filter numbers between x and the square root, because you search for the biggest one.
why do you use the maximum function in getD? you know the list is monotonically growing, so you may as well get the last one.
despite you only need the biggest divisor (which is prime) you compute the divisors list from small to big making the computer check for each value if it is a divisor or not although discarding the result once a bigger divisor is found. it should be fixed by filtering the list of numbers from x to 1, not from 1 to x. this will cause the computer to check divisibility (how should I say that?) for the biggest possible divisor, not throwing to the trash the knowledge of previous checks. note that this optimization takes effect only if the previous point is optimized, because otherwise the computer will compute all divisors anyway.
with the previous points mixed, you should have filtered all numbers [x,x-1 .. squareroot x] and taken the first.
you don't use an efficient isPrime function. if I were you, I would have searched for an isprime library function, which is guaranteed to be efficient.
and there are more..
with this kind of code you will never be able to solve harder project euler problems. they are designed to need extra thinking about the problem (for instance noticing you don't have to check numbers greater from the square root) and writing fast and efficient code. this is the purpose of project euler; being smart about programming. so don't skip it.

Resources