Dougal Stanton ithika at gmail.com
Thu Jul 12 10:55:34 EDT 2007

```On 12/07/07, Crediné Menezes <credine at gmail.com> wrote:
> I have written this code in Haskell which gives an unresolved
> g x             = [2] ++ [3,5..truncate(sqrt x)]
> p  n            = fp n (g  n)
> fp n [ ]        = True
> fp n  (x:xs)  = if (mod n x) == 0 then False else fp n xs
>
> when I submit   g 103
> I get:
> [2,3,5,7,9] :: [Integer]
>
> when I submit: fp 103 (g 103)
> I get
> True :: Bool
>
> But when I submit : p 103
> I get
> *** Type       : (RealFrac a, Floating a, Integral a) => Bool
> *** Expression : p 103
>
> I know why, there is no type that is at the same time: RealFrac, Floating
> and Integral;  but I don´t know how to solve.
>
> What kind of type casting or type definition can I use to fix the error?
>

This one's quite subtle, but as usual getting the inferred types from
GHCi helps immensely:

Prelude> :t p
p :: (Integral a, Floating a, RealFrac a) => a -> Bool
Prelude> :t fp
fp :: (Integral a) => a -> [a] -> Bool
Prelude> :t g
g :: (Integral t, RealFrac a, Floating a) => a -> [t]

The function that doesn't work is the one that calls the other two,
namely p. It doesn't work, but the separate invocation of

> fp 103 (g 103)

does work. So let's look at that one further:

Prelude> :t \x y -> fp x (g y)
\x y -> fp x (g y) :: (RealFrac a1, Floating a1, Integral a) => a -> a1 -> Bool
Prelude> :t \x -> fp x (g x)
\x -> fp x (g x) :: (RealFrac a, Floating a, Integral a) => a -> Bool

The first type signature is for the one that worked, and the second is
for the definition used in the function p. They're different. So the
problem is turning one into the other. In fact, turning (RealFrac a,
Floating a) into (Integral a). Which is what truncate should do:

Prelude> :t \x -> fp (truncate x) (g x)
\x -> fp (truncate x) (g x) :: (RealFrac a, Floating a) => a -> Bool

I hope that helps! ;-)

Cheers,

Dougal.
```