Haskell type declaration

I just started to learn Haskell. I decided to set myself the goal of implementing my old algorithm http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.79.7006&rep=rep1&type=pdf

In the beginning I wrote the following code

phi [] = [1..] phi (p:pl) = (phi pl) `minus` (map (p*) $ phi pl) primes x | x < 2 = [] | otherwise = smallprimes ++ (takeWhile (<=x) $tail $ phi $ reverse smallprimes) where smallprimes = primes $ sqrt x minus (x:xs) (y:ys) = case (compare xy) of LT -> x : minus xs (y:ys) EQ -> minus xs ys GT -> minus (x:xs) ys minus xs _ = xs 

This works as expected, except that the list of primes is a floating point! A little thought told me that since sqrt signature

 sqrt :: (Floating a) => a -> a 

the Haskell compiler decided that primes return a list of floats. However, when I tried to say that

 phi :: [Integer] -> [Integer] 

what i want, the compiler has a problem:

 No instance for (Floating Integer) arising from a use of `sqrt` at ... 

So, how can I indicate that phi accepts a list of integers as input, and since the output creates an infinite list of integers?

+7
source share
2 answers

The problem in your code is that sqrt expects a floating point number and returns the same. You must use a wrapper that converts the type to make it work. (This is essentially what the error message says):

 smallprimes = primes . ceiling . sqrt . fromIntegral $ x 

Haskell does not automatically convert between different numeric types, since this is not possible in the type system that Haskell has.

+6
source

take a look at this: Converting numbers

ceiling should do the trick too (since FUZxxl pointed out allready)

IMHO the hard part here is that the languages ​​we use to create types, pointing to your goal - Haskell switches the logic with a bias of mind here ...

+2
source

All Articles