[Haskell-beginners] Help with types
jason.dusek at gmail.com
Thu Apr 23 10:08:10 EDT 2009
2009/04/23 Daniel Carrera <daniel.carrera at theingots.org>:
> It looks like (/) is happy with Num but doesn't like Int. This
> surprises me. I would have thought that Fractional is a kind
> of Num and Int is a kind of Fractional, so a function that
> expects Fractional would be happy with an Int but maybe not
> with a Num. But clearly that's not the way it works.
In GHCi, let's have a look:
Prelude> :info Int
data Int = GHC.Types.I# GHC.Prim.Int# -- Defined in GHC.Types
instance Bounded Int -- Defined in GHC.Enum
instance Enum Int -- Defined in GHC.Enum
instance Eq Int -- Defined in GHC.Base
instance Integral Int -- Defined in GHC.Real
instance Num Int -- Defined in GHC.Num
instance Ord Int -- Defined in GHC.Base
instance Read Int -- Defined in GHC.Read
instance Real Int -- Defined in GHC.Real
instance Show Int -- Defined in GHC.Show
So `Int` is not actually a kind of `Fractional` (it's
`Integral`, in fact).
Prelude> :t (/)
(/) :: forall a. (Fractional a) => a -> a -> a
So `(/)` needs some `t` that is in `Fractional`.
> 'fromIntegral' converts Int to Num. So obviously, Num is good and Int is
> bad. But I don't really get why.
Actually, `fromIntegral` takes any type `t` that is in
`Integral` and makes it into some other type in `Num` as
appropriate. You can use `fromIntegral` to go from `Int` to
`Integer` or `Word32`, as well.
To work with `(/)` we need a type that is in `Num` and in
`Fractional`. The compiler defaults these *class constraints*
to select, say `Double`. Then `fromIntegral` -- which can take
any `Num` to any other `Num` -- does the "cast" from `Int` to
`Double` for us.
More information about the Beginners