[Haskell] A puzzle and an annoying feature

ajb at spamcop.net ajb at spamcop.net
Wed Nov 24 20:00:22 EST 2004

G'day all.

Quoting Lennart Augustsson <lennart at augustsson.net>:

> Here is a small puzzle.

You can understand this one because the closed world hypothesis doesn't
apply to type context inference.  However, this seems as good a time as
any to mention one of my pet peeves again:

module FD where

class C from to | from -> to where
     g :: from -> to
     h :: to -> from

instance C Char Bool where
     g c = c == 'T'
     h b = if b then 'T' else 'F'

f :: (C Char a) => Char -> a
f c = g c

-- And the error, found in f, is...
    Cannot unify the type-signature variable `a' with the type `Bool'
        Expected type: Bool
        Inferred type: a
    When using functional dependencies to combine
      C Char Bool, arising from the instance declaration at FD.hs:7
      C Char a, arising from a type signature at FD.hs:11
    When generalising the type(s) for `f'

This is a pretty serious problem when you're doing typeclass
metaprogramming.  In this case, the type you're trying to find is
Bool.  In general, it might be a large complex type, generated by
the class C as a typeclass metaprogram, which you don't want to put
in the type signature for maintainability reasons.

Because of the functional dependency on C, the return type of f can
only be one thing.  This partially "closes the world" in a way that
the original program did not.  So in that sense, the declared type of
f is no less general than its "real" type, Char -> Bool.  It would be
nice if Haskell implementations allowed declarations such as this.

Andrew Bromage

More information about the Haskell mailing list