Function that tells if a number ir prime or not - haskell

``
I'm a Haskell newbie and I'm defining a function that given an Int n it tells if a number is prime or not by searching for an 2<=m<=sqrt(n) that mod n m ==0
if such m exists, then n is not prime, if not then n is prime.
I'm trying to define a list with numbers m between 2 and sqrt n, that mod n m ==0
My thought is that if the list is empty then n is prime, it not, n is not prime
`
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
l = [x|x<-[2.. sqrt n], mod n x == 0]
`
But there seems to be a problem with sqrt n when I run my code and I can't understand it. can someone explain what I'm doing wrong/what to change for my code to run/ and why there's an error?

Running the code gives the following error
test.hs:9:28: error:
• No instance for (Floating Int) arising from a use of ‘sqrt’
• In the expression: sqrt n
In the expression: [2 .. sqrt n]
In a stmt of a list comprehension: x <- [2 .. sqrt n]
|
9 | l = [x|x<-[2.. sqrt n], mod n x == 0]
| ^^^^^^
You are correct in saying that the error is with sqrt, but the rest is pretty opaque to a new Haskell developer. Lets try by checking the type of sqrt to see if that helps.
Prelude> :t sqrt
sqrt :: Floating a => a -> a
Here I'm using ghci to interactively write code. :t asks for the type of the preceeding expression. The line sqrt :: Floating a => a -> a says sqrt takes in some floating point number a and returns something of the same type.
Similar to our error message we see this Floating thing. this thing is a typeclass but for the sake of solving this problem we'll save understanding those for later. In essence, haskell is trying to tell you that Int is not floating point number which is what sqrt expects. We can amend that by turning our Int into a Float with fromIntegral which is a really general function for turning number types into one another. (see Get sqrt from Int in Haskell)
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float -- new! - tell fromIntegral we want a float
asFloat = fromIntegral n -- new! turn n into a Float
l = [x|x<-[2..sqrt asFloat], mod n x == 0]
This also errors! but it's a new one!
test.hs:10:48: error:
• Couldn't match expected type ‘Int’ with actual type ‘Float’
• In the second argument of ‘mod’, namely ‘x’
In the first argument of ‘(==)’, namely ‘mod n x’
In the expression: mod n x == 0
|
10 | l = [x|x<-[2..sqrt asFloat], mod n x == 0]
| ^
this is saying that x is suddenly a Float. When we changed to [2..sqrt asFloat] we now have made a list of Floats ([Float]). We need to change that back to [Int]. we can do that by calling floor on the result of the square root.
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float
asFloat = fromIntegral n
l = [x|x<-[2..floor (sqrt asFloat)], mod n x == 0] -- new! I added floor here to change the result of sqrt from a `Float` into a `Int`
This now correctly compiles.

Related

Haskell Type errors

First day learning haskell, and coming from a python background I'm really having trouble debugging when it comes to type; Currently I'm working on a simple function to see if a number is a prime;
prime p = if p == 1 then False else if p == 2 then True else if maximum ([if p `mod` x == 0 then x else -1 | x<-[2..(floor(p**0.5))]]) > 0 then False else True
It works when I have a specific number instead of the generic P, but no matter what I try (and I've tried a lot, including just moving onto different problems) I always get some kind of error regarding type. For this current iteration, I'm getting the error
<interactive>:149:1: error:
* Ambiguous type variable `a0' arising from a use of `prime'
prevents the constraint `(RealFrac a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance RealFrac Double -- Defined in `GHC.Float'
instance RealFrac Float -- Defined in `GHC.Float'
...plus one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the expression: prime 2
In an equation for `it': it = prime 2
<interactive>:149:7: error:
* Ambiguous type variable `a0' arising from the literal `2'
prevents the constraint `(Num a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance Num Integer -- Defined in `GHC.Num'
instance Num Double -- Defined in `GHC.Float'
instance Num Float -- Defined in `GHC.Float'
...plus two others
...plus one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the first argument of `prime', namely `2'
In the expression: prime 2
In an equation for `it': it = prime 2
If someone could, as well as debugging this particular program, give me a heads up on how to think of haskell types, I'd be incredibly grateful. I've tried looking at learnyouahaskell but so far I've had no luck applying that.
In short: by using mod, floor, and (**) all at the same time, you restrict the type of p a lot, and Haskell fails to find a numerical type to call prime.
The main problem here is in the iterable of your list comprehension:
[2..(floor(p**0.5))]
Here you call p ** 0.5, but since (**) has type (**) :: Floating a => a -> a -> a, that thus means that p has to be an instance of a type that is an instance of the Floating typeclass, for example a Float. I guess you do not want that.
Your floor :: (RealFrac a, Integral b) => a -> b even makes it worse, since now p also has to be of a type that is an instance of the RealFrac typeclass.
On the other hand, you use mod :: Integral a => a -> a -> a, so it means that your p has to be Floating, as well as Integral, which are rather two disjunctive sets: although strictly speaking, we can define such a type, it is rather weird for a number to be both Integral and Floating at the same type. Float is for instance a Floating number, but not Integral, and Int is Integral, but not a Floating type.
We have to find a way to relax the constraints put on p. Since usually non-Integral numbers are no primes at all, we better thus aim to throw out floor and (**). The optimization to iterate up to the square root of p is however a good idea, but we will need to find other means to enforce that.
One way to do this is by using a takeWhile :: (a -> Bool) -> [a] -> [a] where we take elements, until the square of the numbers is greater than p, so we can rewrite the [2..(floor(p**0.5))] to:
takeWhile (\x -> x * x <= p) [2..]
We even can work only with odd elements and 2, by writing it as:
takeWhile (\x -> x * x <= p) (2:[3, 5..])
If we test this with a p that is for instance set to 99, we get:
Prelude> takeWhile (\x -> x * x <= 99) (2:[3, 5..])
[2,3,5,7,9]
If we plug that in, we relaxed the type:
prime p = if p == 1 then False else if p == 2 then True else if maximum ([if p `mod` x == 0 then x else -1 | x <- takeWhile (\x -> x * x <= p) (2:[3, 5..])]) > 0 then False else True
we actually relaxed it enough:
Prelude> :t prime
prime :: Integral a => a -> Bool
and we get:
Prelude> prime 23
True
But the code is very ugly and rather un-Haskell. First of all, you here use maximum as a trick to check if all elements satisfy a predicate. But it makes no sense to do that this way: from the moment one of the elements is dividable, we know that the number is not prime. So we can better use the all :: (a -> Bool) -> [a] -> Bool function. Furthermore conditions are usually checked by using pattern matching and guards, so we can write it like:
prime :: Integral a => a -> Bool
prime n | n < 2 = False
| otherwise = all ((/=) 0 . mod n) divisors
where divisors = takeWhile (\x -> x * x <= n) (2:[3, 5..])
Your code can be simplified as
prime p = if p == 1 then False else
if p == 2 then True else
if maximum ([if p `mod` x == 0 then x else -1 | x<-[2..(floor(p**0.5))]]) > 0
then False else True
=
prime p = if p == 1 then False else
if p == 2 then True else
not (maximum [if p `mod` x == 0 then x else -1 | x<-[2..floor(p**0.5)]] > 0 )
=
prime p = not ( p == 1 ) &&
( p == 2 ||
maximum [if p `mod` x == 0 then x else -1 | x<-[2..floor(p**0.5)]] <= 0 )
=
prime p = p /= 1 &&
( p == 2 ||
maximum [if p `mod` x == 0 then x else -1 | x<-[2..floor(p**0.5)]] == -1 )
=~
prime p = p == 2 || p > 2 && null [x | x <- [2..floor(p**0.5)], p `mod` x == 0]
(convince yourself in the validity of each transformation).
This still gives us a type error of course, because (**) :: Floating a => a -> a -> a and mod :: Integral a => a -> a -> a are conflicting. To counter that, just throw a fromIntegral in there:
isPrime :: Integral a => a -> Bool
isPrime p = p == 2 ||
p > 2 && null [x | x <- [2..floor(fromIntegral p**0.5)], p `mod` x == 0]
and it's working:
~> filter isPrime [1..100]
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]

Haskell: last digit of a very large number

I'm trying to work out the last digit of a very large number. The challenge is that I'm getting the error
*** Exception: Prelude.!!: negative index
which I don't think should be possible. This happens when I try:
lastDigit [27,15,14]
Here is my code, which is based on https://brilliant.org/wiki/finding-the-last-digit-of-a-power/:
In this case, n becomes 7 and modList 7 gives the recurring sequence [1,7,9,3,1,7,9,3...], which is the first argument of (!!) in the relevant guard. The second argument of (!!) gives 1 because (y:ys) is (15,14) and rem (powers (15 ^ 14)) 4 is 1. Please help.
lastDigit :: [Integer] -> Integer
lastDigit [] = 1
lastDigit [x] = x `mod` 10
lastDigit [x,y] = x ^ y `mod` 10
lastDigit (x:y:ys)
| y == 0 && head ys /= 0 = 1
| n == 0 = 0
| n == 9 || n == 4 = (!!) (modList n) (rem (fromIntegral $ powers (y:ys)) 2)
| n == 2 || n == 3 || n == 7 || n == 8 = (!!) (modList n) (rem (fromIntegral $ powers (y:ys)) 4)
| otherwise = n
where n = mod x 10
powers xs = foldr1 (^) xs
modList n = drop 3 . take 30 $ cycle [mod x 10| x <- map (n^) $ take 4 [1..]]
You should be very specific about the types, otherwise they might get implicit converted during calculations. If you add Int type to your algorithm, ghc will not complain and run into an negative index exception
(fromIntegral $ powers (y:ys)) 2 :: Int)
but if you provide
(fromIntegral $ powers (y:ys)) 2 :: Integer)
it will result in
• Couldn't match expected type ‘Int’ with actual type ‘Integer’
• In the second argument of ‘(!!)’, namely
‘(rem (fromIntegral $ powers (y : ys)) 2 :: Integer)’
As you can see you have an implicit Int conversion there. Try to split up your function into smaller ones and provide a type signature, then you should be able to successfully align the types and calculate with Integers instead of Int.

Compute prime in haskell

I wish to compute whether a given integer is prime in Haskell:
--primes
isPrime :: (Integral a) => a -> Bool
isPrime n | n < 4 = n > 1
isPrime n = all ((/=0).mod (n-1)) $ 2:3:[x + i | x <- [6,12..s], i <- [-1,1]]
where s = floor $ sqrt $ fromIntegral n
However, running this on the input 131 gives False. I think the error lies in modular arithmetic but I'm not sure. Is there anything wrong with the modular statement in my program?

Haskell Error: "No instance for (Enum [Int])

I have the following code:
betaRest :: Int -> [Int] -> Int
betaRest n prevDigits | n == 0 = (length prevDigits)
| otherwise = (sum (map (betaRest (n - 1)) [0..9]))
betaFirst :: Int -> Int
betaFirst n | n == 0 = 0
| otherwise = (betaRest (n - 1) [1..9])
It gives me the following errors, and I don't know why.
1) No instance for (Enum [Int]) arising from the arithmetic sequence '0 .. 9'
2) No instance for (Num [Int]) arising from the literal '0'
Does Haskell think that things made with the ".." operator are enumerations? But why isn't there an error for the line that's 4 lines below (with "[1..9]") it then?
Edit: What I want the code to do is like this (procedurally):
int betaRest(int n, int[] prevDigits) {
if (n == 0) return prevDigits.length;
else {
sum = 0;
foreach prevDigit in prevDigits {
sum += betaRest(n - 1, [0..9]);
}
return sum;
}
}
int betaFirst(int n) {
if (n == 0) return 0;
else return betaRest(n - 1, [1..9]);
}
Thus, betaFirst(1) == 9, and betaFirst(2) == 90. Yes, somebody may want to suggest a formula for generating this, but I'm going to add a filter of some sort to [0..9], thus reducing the range.
You pass betaRest to map. Map is (a -> a) -> [a] -> [a] so for [Int] list you pass it it wants an Int -> Int function. But partially applied betaRest is [Int] -> Int.
As for [0..9] its type is (Enum t, Num t) => [t] and it's translated into enumFromTo 0 9 application. So compiler figured your error the other way around: if you define special Num and Enum instances for lists, so [0..9] becomes a list of lists of int, then your application will make sense.
But I think you want to use inits or tails function. Let us know what you want to achieve so we can help with solution.
A minimal fix to would be to add prevDigits as an argument to map and use a lambda abstraction to ignore unused prevDigit:
| otherwise = sum (map (\prevDigit -> betaRest (n - 1) [0..9]) prevDigits)
(sum (map (betaRest (n - 1)) [0..9]))
Let's reduce the number of parentheses to better be able to see what happens.
sum (map (betaRest (n - 1)) [0..9])
The argument of sum is
map (betaRest (n-1)) [0 .. 9]
Now, betaRest :: Int -> [Int] -> Int, hence the type of the partially applied function is
betaRest (n-1) :: [Int] -> Int
hence we can infer the type
map (betaRest (n-1)) :: [[Int]] -> [Int]
But the argument passed to map (betaRest (n-1)) is [0 .. 9], which has type
[0 .. 9] :: (Num a, Enum a) => [a]
The Num constraint comes from the use of an integer literal, and the Enum constraint from the use of the enumFromTo function (in its syntax-sugared form [low .. high]). Passing that as an argument to a function expecting an argument of type [[Int]] means the type variable a must be instantiated as [Int], and then the constraints need to be checked, i.e. the instances of [Int] for Num and Enum must be looked up. Neither of these exist, hence the error messages.
I'm not sure your procedural example is really what you want,
int betaRest(int n, int[] prevDigits) {
if (n == 0) return prevDigits.length;
else {
sum = 0;
foreach prevDigit in prevDigits {
sum += betaRest(n - 1, [0..9]);
}
return sum;
}
}
the foreach loop is much easier (and more efficiently) expressed as
sum = prevDigits.length * betaRest(n-1, [0 .. 9]);
so for the foreach to make sense, there should be a dependence on prevDigit in the loop body.
The translation to Haskell would be
betaRest n prevDigits
| n == 0 = length prevDigits
| otherwise = length prevDigits * betaRest (n-1) [0 .. 9]
-- or with the loop, with the small improvement that `betaRest (n-1) [0 .. 9]
-- is only computed once (if the Haskell implementation is sensible)
-- | otherwise = sum $ map (const $ betaRest (n-1) [0 .. 9]) prevDigits
But as stated above, I doubt that's really what you want.

haskell list of primes construction; ambiguos type variable

I'm trying to make function primes which is a list of prime numbers, but somehow I have failed. The compiler throws an error I don't know how to resolve:
Error:
Ambiguous type variable 'a0'
Code:
candidates :: [Integer]
candidates = [2]++[3,5..]
primes :: [Integer]
primes = filter is_prime candidates
is_prime :: Integer -> Bool
is_prime candidate
| candidate == 1 = False
| candidate == 2 = True
| candidate == 3 = True
| otherwise = r_is_prime candidate 0
-- r as recursive
r_is_prime :: Integer -> Integer -> Bool
r_is_prime candidate order
| n_th_prime >= max_compared_prime = True
| candidate `mod` n_th_prime == 0 = False
| otherwise = if (r_is_prime candidate (order+1) ) then True else False
where
n_th_prime = candidates !! fromIntegral(order)
-- this is the line that throws an error...
max_compared_prime = fromIntegral ( ceiling ( fromIntegral ( sqrt ( fromIntegral candidate))))
In
max_compared_prime = fromIntegral ( ceiling ( fromIntegral ( sqrt ( fromIntegral candidate))))
you have a fromIntegral too much. sqrt has type
sqrt :: Floating a => a -> a
so the result of sqrt is not a member of an Integral type. And the result of ceiling is an Integral type, so the last fromIntegral is superfluous (but does not harm).
max_compared_prime = ceiling ( sqrt ( fromIntegral candidate))
is all you need in that line.
Note, however, that
n_th_prime = candidates !! fromIntegral(order)
means that to test against the n-th candidate prime, the list of candidates has to be traversed until the n-th prime has been reached. Thus testing against the n-th candidate is O(n) here instead of O(1) [Well, assuming that numbers are bounded] which a single division is.
A more efficient trial division only tries primes for the division and remembers where in the list of primes it was when it goes on to the next prime. For example
is_prime :: Integer -> Bool
is_prime n
| n < 2 = False
| n < 4 = True
| otherwise = trialDivision primes
where
r = floor (sqrt $ fromIntegral n)
trialDivision (p:ps)
| r < p = True
| otherwise = n `rem` p /= 0 && trialDivision ps
Just traverses the list of primes in order to do the trial division, hence going from one prime to the next is a simple step in the list.
You have too many fromIntegrals in
max_compared_prime = fromIntegral ( ceiling ( fromIntegral ( sqrt ( fromIntegral candidate))))
The fromIntegral applied to the result of sqrt is causing the error. If we look at the type signatures, we have:
fromIntegral :: (Num b, Integral a) => a -> b
sqrt :: Floating a => a -> a
So to properly infer the type of fromIntegral (sqrt x) Haskell needs to find a type with both Floating and Integral instances (so that the result of sqrt matches the parameter of fromIntegral). Haskell can't find such a type and so (basically) is asking you to specify one (but there isn't one). The solution is to just elide this fromIntegral:
max_compared_prime = fromIntegral ( ceiling ( sqrt ( fromIntegral candidate)))
other notes
Brackets aren't particularly idiomatic Haskell, so that line can/should be written as:
max_compared_prime = fromIntegral . ceiling . sqrt . fromIntegral $ candidate
Furthermore, the result of ceiling doesn't need to be converted, so it can even be:
max_compared_prime = ceiling . sqrt . fromIntegral $ candidate
Remove 'fromIntegral' from before 'sqrt', as:
max_compared_prime = fromIntegral ( ceiling ( sqrt ( fromIntegral candidate)))
The types are:
sqrt :: Floating a => a -> a
fromIntegral :: (Integral a, Num b) => a -> b
the output of sqrt is 'Floating', not Integral.

Resources