Go to the first, previous, next, last section, table of contents.

Types

A big new thing in Haskell 1.3 is constructor classes. Humble old functions such as `map' now have an exciting new type:
map :: Functor f => (a->b) -> f a -> f b
These new overloadings, expecially where it's the type constructor that's overloaded (as in `map') can give rise to some puzzling error messages. For example:
----------------------------------------------------------------------
  lookupColor :: String -> [(String, (a, b, c))] -> (a, b, c)
  lookupColor colorName colorTable =
        head [(r,g,b) | (c,(r,g,b)) <- colorTable, c == map toLower colorName]
----------------------------------------------------------------------
With the type signature this is fine, but if you omit the type signature you'll get:
  "Color.hs", line 49: No instance for: Prelude.Eq (a{-a18d-} Prelude.Char)
    "Color.hs", line 49:
        at a use of an overloaded identifier: `Prelude.meth.Prelude.Eq.=='
`map' no longer says that `colorName' has to be a list; it could be any type of the form (t `Char'). Unfortunately, lookupColor has to take equality over these (t `Char') things, so it gets stuck trying to figure out how to resolve (`Eq' (t `Char')) when it knows nothing about t. The solution to such messages is to add type signatures.
Go to the first, previous, next, last section, table of contents.