I'm currently learning Haskell using the Gentle Introduction to Haskell website, and I took a break halfway into section 4 to test my knowledge. I'm trying to implement a "greatest prime in a composite number" function that I used when I was working in C, but I'm having trouble with Haskell's typing system. I'm trying to pass a number that looks like it's a fractional Int, but because I've used modulus to check if it's divisible, I know will evaluate to an Int. Here's the context:
The C: I've super-commented it in case it's unclear, but the code should be fairly straightforward.
int highest(long currDom, long lastLargest, long currMax)
/* This is a recursive function that starts at the lowest prime number, 2,
* and divides into currMax. If a division operation is even - modulus returns 0 -
* then the prime number in the division is saved as "lastLargest," and the
* function calls itself again, with MAX now passed as MAX/lastLargest. Otherwise,
* the function is called with currMax remaining the same value, and the
* current denominator to try (currDom) incremented by one.
*/
{
if (currDom > currMax) //end result - when the current value of MAX is less
return lastLargest; //than the value of the denominator we're trying, we're done
else
{
if (currMax % currDom == 0) //if modulus succeeds, try again with Max/currDom
return highest(currDom, currDom, currMax/currDom); //denominator is kept the same incase
else //it goes into MAX multiple times -e.g. 2 into 8
return highest(currDom+1, lastLargest, currMax); //else, try the next denominator.
}
}
If you were looking for the highest in 10, for example, you would call this by saying "highest(10, 2, 1)" - you're looking for the highest prime in 10, starting at 2, and the current highest prime in the number is 1. It would return when it tried the number 5 as a divisor for the second time, and saw that curDom is now 1.
The problem is that when I try this in Haskell, on the fourth line in my code, I run into an issue with passing the number divided by a prime that goes into it - it appears to be a fractional Int, but because I've already checked with modulus, I know it's going to resolve to a regular Int. Here's the code I'm working with:
greatestPrime :: Int -> Int -> Int -> Int
greatestPrime num curPrime greatest | (curPrime > num) = greatest
greatestPrime num curPrime greatest | (mod num curPrime) > 0 = greatestPrime num (curPrime+1) greatest
greatestPrime num curPrime greatest | (mod num curPrime) == 0 = greatestPrime (num/curPrime) curPrime greatest
If you were trying to get the highest prime in 10, for example, you would call this with "greatestPrime 10 2 1", so that you would start searching at 2, and your current greatest prime number would be 1.
I would appreciate any help with this - either by helping with type aliasing, general code implementation, or even syntax/ code blocking. I'm new to haskell, so there may be a way of writing this that makes more sense; however, I'm not looking for full algorithm rewrites like a sieve. Thanks for your time.
The /
operator has type (/) :: Fractional a => a -> a -> a
, which means that it only works on Fractional
types like Float
, Double
and Rational
, and not integers.
Use div :: Integral a => a -> a -> a
for integer division.
> 10 `div` 2
5
> 7 `div` 2
3
There's also quot
, which rounds towards zero instead of negative infinity:
> (-7) `div` 2
-4
> (-7) `quot` 2
-3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With