{-# 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
Nothing
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/
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe