Jason Dagit wrote: > 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.
This would be very bad, but I doubt it is possible. > 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! What's the problem? > 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. Right. You must call the data constructor Foo in order to exploit that it has the type Foo :: Int -> Foo a I don't see how this is not type safe, and I was not able to produce an #unsafeCoerce with this technique. One would need some unFoo a -> a but the a in data Foo a is phantom, i.e. there is no thing of type a in a Foo. Cheers Ben _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
