[Haskell-cafe] translating bidirectional fundeps to TFs

Dan Doel dan.doel at gmail.com
Fri Sep 17 16:19:24 EDT 2010

On Friday 17 September 2010 4:04:26 pm Gábor Lehel wrote:
> What I would *want* to write is this:
> class (Mutable (Thawed a), Frozen (Thawed a) ~ a) => Immutable a where
>     type Thawed a :: *
>     thaw :: a -> Thawed a
> class (Immutable (Frozen a), Thawed (Frozen a) ~ a) => Mutable a where
>     type Frozen a :: *
>     freeze :: a -> Frozen a
> This looks considerably nicer, but it's not valid -- I get a cycle in
> class declarations via superclasses error, on the one hand, and (if I
> remove that) an infinite loop in the typechecker (context reduction
> stack overflow) on the other (FlexibleContexts being a prerequisite
> for most of the interesting things you can do with TypeFamilies).
> So what should one, theoretically, do here? Is there a way to express
> this using TypeFamilies which preserves both the semantics and the
> symmetry of the FDs version, and is also valid? Or should one just go
> ahead and use the FDs because, in this case, they're simply better
> suited? *Or* should one just suck it up and go with the ugly
> TypeFamilies version because TypeFamilies are The Future*?

What about:

  class (Thawed frozen ~ thawed, Frozen thawed ~ frozen)
        => TwoPhase thawed frozen where
    type Thawed frozen :: *
    type Frozen thawed :: *
    thaw   :: frozen -> thawed
    freeze :: thawed -> frozen

This is the translation I'd expect for the fundep. And ideally, in the future, 
you could use the original class with fundeps as sugar for the above, because 
fundeps are a nice way of expressing mutual dependency like this (just as 
associated types are nicer than making the associated type a class parameter 
as is required by fundeps).

-- Dan

More information about the Haskell-Cafe mailing list