"Marcin 'Qrczak' Kowalczyk" <mk167280@zodiac.mimuw.edu.pl> wrote,
On Tue, 28 Nov 2000, Simon Peyton-Jones wrote:
Simon and I noticed this morning that ForeignObj should really be parameterised.
I was considering it too and IMHO it does not need to be parametrized.
Values implemented as foreign objects are often exposed to the user of the module. For this reason they are usually wrapped in newtypes to make them truly abstract. So we don't worry for the external interface - it is safe anyway, the objects will not be mistaken for something from a different library.
Values kept under foreign objects are usually C structs which don't have a Haskell equivalent. If the type was simple (e.g. struct RGB {double r, g, b;};), it would be represented as a Haskell record. Since the type needs a finalizer, it usually means that it's complex enough to be not exported concretely by a C library, so there is no appropriate Haskell type to make a Storable instance - it will be accessed only through functions imported from C. And since it's complex enough, it will not be marshalled as a whole - instead its fields will be extracted as needed. And since it's finalized, it usually means that its lifetime is important because it represents some external resource, so it will really not be ever marshalled!
That actually also matches my experience. Foreign objects are usually used as a kind of foreign "abstract data types". Their values are only used as arguments to external routines and nothing else. This is very different to `Ptr a' values, where we use our knowledge of `a' to peek and poke into the concrete structure refereed to by the pointer. However, I can also related to what Simon said,
It's bizarre to have withForeignObj :: ForeignObj -> (Ptr a -> IO b) -> IO b
So, how about the following? Instead of the newtype Window = Window ForeignObj way of wrapping foreign ADTs that we used so far, should we use newtype WindowTag = WindowTag () type Window = ForeignObj WindowTag ? This way, we would have the uniformity of having parametrised ForeignObj and make good use of the parameter? Cheers, Manuel