G'day all. Quoting Lennart Augustsson <lennart@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... {- FD.hs:12: 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. Cheers, Andrew Bromage