
Simon Peyton-Jones:
| > * Clarify the spec to say that a newtype can only be automatically | > unwrapped if the newtype constructor (MkN in this case) is in | > scope | | I agree up to here. For user-defined types, not exporting the | constructor should be a guarantee of abstraction.
I also don't really see an alternative. The ability to pass a type to a foreign function tells us something about the type; there is not much we can do about that.
| > It happens that a large set of types from Foreign.C.Types, such as | > CInt and friends, are exported without their constructors, so adopting | > this new rule would require us to change Foreign.C.Types to expose the | > representation of CInt and friends. (As it happens, nhc requires this | > already, so there's some #ifdeffery there already.) | | The thing about CInt though is that it is supposed to be abstract *and* | an FFI type. I want to think of it as a primitive FFI type (though it is | not a "basic" type as defined by the FFI). We don't want to know that on | some system it is Int32 and on others it is Int64. We do not want access | to the constructor here.
Trouble is, there are a zillion types in Foreign.C.Types, and another zillion in Foreign.Posix.Types. Do you want to list them all as "blessed" in the FFI addendum?
The types in Foreign.C.Types are already listed in the FFI addendum (it actually specifies the whole module, just like the report specifies what is in the Prelude). However, I think an argument can be made that hiding the implementation of the types in C.Foreign.Types is a Bad Thing. FFI code is inherently architecture dependent due to the varying sizes and representations of C types. Hiding that variation behind a newtype serves only to obscure that dependency, it certainly doesn't resolve it. I know that Section 6.2 of the FFI addendum requires these exports to be abstract, but I now tend to think that this was a mistake. Manuel