Daniel Carrera daniel.carrera at theingots.org
Thu Apr 23 12:26:02 EDT 2009

```Daniel Fischer wrote:
> Not quite. (/) needs a type which is an instance of Fractional. All instances of
> Fractional are also instances of Num, so Fractional is more specific than Num.
> If you divide the result of sum using (/), sum is used at the less general type
> (Fractional a => [a] -> a).
> Every function can be used at all types which are less general than its most
> general type.

Aahh....  I see. The "sum" part is making more sense now.

So let's see: "sum" is a (Num a => [a] -> a). Every function can be used
at all types that are less general than its most general type.
Fractional is a kind of Num. Therefore, "sum" can be used as (Fractional
a => [a] -> a) to make it compatible with (/).

Thanks for the detailed explanation. It's a lot clearer now.

>> This surprises
>> me. I would have thought that Fractional is a kind of Num and Int is a
>> kind of Fractional,
>
> No, Int is an instance of Integral, which is sort of the opposite of Fractional.
> Fractional means that you can freely divide (excluding division by 0 of course), things
> like 3.24 make sense, Integral means that things like mod or gcd make sense.
> Though it is possible to make a type an instance of both, Fractional and Integral, that
> doesn't really make sense.

This helps. I think I see the problem:

Suppose that Integral was a kind of Fractional, the way I proposed. What
happens when someone writes (x / y) `mod` z ?  Trying to apply the same
reasoning you used above:

(/) :: Fractional a => a -> a -> a
mod :: Integral a => a -> a -> a

Using the logic that you explained above, we would have to force (/) to
give an Integral result, which in general is wrong. And that is a
reasonable argument why Integral should not be an instance of Fractional.

Am I right more or less?

>> But I don't really get why.
>
> fromIntegral says, whatever Num type you want, I can give it to you.

... and 'length' says, "whatever Int type you want, I can give it to
you", but (/) says "I don't want an Int, I want a Fractional" and that's
why 'length' alone doesn't get along with (/).

I'm beginning to see the reasoning behind Haskell's behaviour, but I
think I'll need time to get used to it.

Thanks for the help.

Daniel.
```