fundeps help

Simon Peyton-Jones simonpj at
Mon Dec 3 04:02:45 EST 2007

| I'm trying to understand what fundeps do and don't let me do. One
| particular source of confusion is why the following program doesn't
| typecheck:
| {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
| module Fundeps where
| class Dep a b | a -> b, b -> a
| conv :: (Dep a b1,Dep a b2) => b1 -> b2
| conv = id
| {- end of program -}

GHC implements "improvement" by *identifying* the two equal types.  Here they cannot be identified because they are separate type variables.  A good way to think of this is to imagine translating the program into System F: you can't do it.  Functional dependencies guide type inference by adding extra unifications, resolving types that would otherwise be under-constrained and ambiguous -- but fundeps (or at least GHC's implementation thereof) does not deal with the case where the types become *over*-constrained.

GHC's new intermediate language, System FC, is specifically designed to do this.  Currently we're in transition: equality constraints are starting to work, but fundeps are implemented as they always were.  I hope we can eventually switch over to implementing fundeps using equality constraints, and then the above program will work.

Meanwhile, in the HEAD you can write
        conv :: (a~b) => a -> b
        conv = id

Which, IHMO, is a much clearer way to say it!

You may also like to try the paper that Martin and I and others wrote about fundeps:


More information about the Glasgow-haskell-users mailing list