[Haskell-cafe] RE: MPTCs and rigid variables

C Rodrigues red5_2 at hotmail.com
Sat Mar 3 13:48:32 EST 2007

>{-# OPTIONS_GHC -fglasgow-exts #-}
>class Foo a b | a -> b where
>   foo :: Foo b c => a -> Maybe c
>instance Foo String () where foo _ = Nothing
>instance Foo Int String where foo 4 = Just (); foo _ = Nothing

There appears to be a type-safe way to use unsafeCoerce# for this:

import qualified GHC.Exts

class Foo a b | a -> b where foo :: a -> FooBox b
data FooBox b = forall c. Foo b c => FooBox (Maybe c)

instance Foo () ()
instance Foo String () where foo _ = FooBox Nothing
instance Foo Int String where foo 4 = FooBox $ Just (); foo _ = FooBox 

runFoo :: (Foo a b, Foo b c) => a -> Maybe c
runFoo x = case foo x of FooBox x -> GHC.Exts.unsafeCoerce# x

The class constraint check of a,b,c gets moved to the runFoo method instead 
of the instance declarations.  Between the body of foo and the call to foo 
in runFoo, type 'c' is unknown to the compiler, so we have to encapsulate it 
in a FooBox.  The unsafeCoerce# is safe because the type constraint (Foo b 
c) that we've placed both on FooBox and on runFoo permits c to have only the 
type uniquely specified by b.

We actually could remove the Foo constraint on FooBox, which makes the code 
no longer typesafe but it will still work just fine.

Don’t miss your chance to WIN 10 hours of private jet travel from Microsoft® 
Office Live http://clk.atdmt.com/MRT/go/mcrssaub0540002499mrt/direct/01/

More information about the Haskell-Cafe mailing list