On Wed, Aug 6, 2008 at 11:09 AM, Andrew Coppin <[EMAIL PROTECTED]>wrote:
> I just (re)discovered that I can do things like > > data Foo x = Foo Int Int > > Now "Foo Int" and "Foo Double" are, as far as the type checker cares, two > completely different types, even though in fact they are the same. This is > actually Quite Useful, in the particular case I'm working on. Phantom types are indeed useful for many things, but a bit of cautionary advice. If you start to depend on the phantoms for type safety AND you export your data constructors then you run a serious risk of being type unsafe. Bonus points if you can demonstrate an equivalent of unsafeCoerce# this way. Example: fooCast :: Foo Int -> Foo Double fooCast (Foo x) = Foo x On noes! We just cast that Foo Int to a Foo Double without changing it! It works because the value on the RHS is consider freshly constructed and other than sharing x it is unrelated to the one on the LHS. Note that by contrast this does not type check: foo :: Foo Int -> Foo Double foo f@(Foo x) = f Or, for that matter, any other variant where you don't use the constructor on the RHS. One way to get around this is to create your own constructor functions: mkFooInt :: Int -> Foo Int mkFooInt = Foo mkFooDouble :: Int -> Foo Double mkFooDouble = Foo Now export these instead of your data constructor. Similarly you'll probably want ones to take the place of pattern matching. The most obvious general purpose one being: unFoo :: Foo a -> Int unFoo (Foo a) = a But, if you're really relying on that phantom as a "witness", then you should probably define separate unFooInt :: Foo Int -> Int and unFooDouble : Foo Double -> Int. Here is the part where it gets really interesting. If you use GADTs, it rolls some of the above into one nice declaration: data Foo a where FooInt :: Int -> Foo Int FooDouble :: Int -> Foo Double I'm not sure if the GADT way can lead to an unsafeCoerce# equivalents or not. Maybe someone else can comment on that. Jason
_______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
