[Haskell-beginners] Help with types

Jason Dusek 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.

--
Jason Dusek


More information about the Beginners mailing list