[Haskell-cafe] translating bidirectional fundeps to TFs

Dan Doel dan.doel at gmail.com
Sat Sep 18 16:31:59 EDT 2010

On Saturday 18 September 2010 8:27:45 am Gábor Lehel wrote:

> Hmm. I had a similar thought, but dismissed it because I was under the
> impression that you needed to use all the parameters of the class as
> parameters of its associated types. But apparently that was mistaken
> -- or, at least, your example compiles. :)

Classes of the form I sent:

  class (T1 b ~ a, T2 a ~ b) => C a b where
    type T1 b :: *
    type T2 a :: *

actually desugar into the following:

  type family T1 b :: *
  type family T2 a :: *

  class (T1 b ~ a, T2 a ~ b) => C a b where

So the parameters of the families needn't match the parameters of the class. 
It does impose some additional constraint on your making instances of the 
families whenever you make an instance of the class, which wouldn't be there 
if you wrote them separately, but I think that's it.

This is also important when translating classes like the following:

  class Closed a | -> a where

You can only write a single instance of that class (although, I'd guess that 
GHC currently accepts 'instance Closed a where ...', which should be illegal). 
To translate it to type families, you write:

  class Closed a where
    type T :: *

a family with no parameters. The compiler will only allow you to write one 
instance for that family, but you must provide an instance for each instance 
of the Closed class. Hence, you can only write a single instance of the Closed 

-- Dan

More information about the Haskell-Cafe mailing list