Aaron
Aaron

Reputation: 75

Unresolved Instance Declaration

I have two functions , one to get the squareRoot of a number which differs from the previous item by < 0.0001 , approx is fine.

squareRoot n = squareRoot' (approx n)

squareRoot' ( n : n2 : ns ) | abs (n2 - n) < 0.0001 = n2
                            | otherwise = squareRoot' ( n2 : ns )

And another which uses it to list the infinite list of primes

primes = [ n | n <- [ 2 .. ], isPrime n ]

isPrime 2 = True
isPrime 3 = True

isPrime n = isPrime' n (squareRoot n) primes

isPrime' n squareRoot (h : t)   
   | h < squareRoot && mod n ( h :: Int ) /= 0 = False
   | otherwise = isPrime' n squareRoot t

I simple cannot see the instance declaration that I must make that results in

No instance for (Fractional Int) arising from a use of `squareRoot'
Possible fix: add an instance declaration for (Fractional Int)
In the second argument of isPrime', namely `(squareRoot n)'
In the expression: isPrime' n (squareRoot n) primes
In an equation for `isPrime':
    isPrime n = isPrime' n (squareRoot n) primes

Could someone help me out ? Thanks

Upvotes: 1

Views: 50

Answers (1)

Random Dev
Random Dev

Reputation: 52280

aside from the things already mentioned in the comments I think that you want to use your squareRoot to got only to sqrt p while checking for divisors for your isPrime predicate right?

if so, then instead of using conversion and sqrt and stuff you can just make use of

m <= sqrt n <=> m^2 <= n

like this:

isPrime :: Integer -> Bool
isPrime 1 = False
isPrime p = null [ d | d <- takeWhile (\ m -> m^2 <= p) [2..], p `mod` d == 0 ]

and get:

λ> take 20 primes
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71]

as well ;)


in case you are looking for a way to get floor (sqrt p) for (I assume approx is some kind of algorithm to get you a series of numbers to calculate roots), than using the same observation this would just be

sqrtn :: Integer -> Integer
sqrtn n = head [ m | m <- [n,n-1..1], m^2 <= n ]

Upvotes: 2

Related Questions