
All, I'm after advice on whether the following example is a safe use of unsafeCoerce, and if it is safe, if it's worth it. In summary, if the following is ok: castFooToBar :: Ptr Foo -> Ptr Bar castFooToBar = castPtr then is the following ok? newtype Foo' = Foo' (Ptr Foo) newtype Bar' = Bar' (Ptr Bar) castFooToBar' :: Foo' -> Bar' castFooToBar' = unsafeCoerce Here's the context/motivation: In the gtk2hs bindings for Haskell we model Gtk's object hierarchy by a hierarchy of Haskell classes and corresponding instances (and newtypes of ForeignPtrs). Here's the pattern: --The base class: newtype GObject = GObject (ForeignPtr GObject) mkGObject = GObject unGObject (GObject o) = o class GObjectClass o where toGObject :: o -> GObject fromGObject :: GObject -> o instance GObjectClass GObject where toGObject = id fromGObject = id --A derived class newtype Widget = Widget (ForeignPtr Widget) mkWidget = Widget unWidget (Widget o) = o class GObjectClass o => WidgetClass o toWidget :: WidgetClass o => o -> Widget toWidget = fromGObject . toGObject fromWidget :: WidgetClass o => Widget -> o fromWidget = fromGObject . toGObject instance WidgetClass Widget instance GObjectClass Widget where toGObject = mkGObject.castForeignPtr.unWidget fromGObject = mkWidget.castForeignPtr.unGObject So you can see in the instance of Widget for the GObjectClass we're basically doing a pointer cast (and wrapping & unwrapping newtypes). In C they just cast pointers. I'm wondering if we can do the same, ie define the instance like so: instance GObjectClass Widget where toGObject = unsafeCoerce fromGObject = unsafeCoerce Of course there's not much point, but if we know that toGObject & fromGObject are just doing a cast, then we can get rid of the class methods on GObjectClass and just implement them as ordinary class constrained functions: toGObject :: GObjectClass o => o -> GObject toGObject = unsafeCoerce fromGObject :: GObjectClass o => GObject -> o fromGObject = unsafeCoerce So, the point is we can remove entirely the class dictionary that otherwise has to be carried round for every object and the upcasting & downcasting functions no longer need to do slow dictionary lookups when all they are really doing is casting C pointers. So is it a) safe? b) kosher? BTW I know fromGObject is doing an unchecked downcast, it is only used internally, we have safe checked ones that we expose in the interface. Duncan