
Daniel Cartwright wrote:
There is no operational difference when using `Ptr a` vs `Addr` in such a case. The problem lies in the type variable `a`. Types are here to guide us - if I use `Ptr Word8`, and this Ptr is not a Ptr to Word8, there is not much enforcing this. In such cases, the type annotation is untruthful.
This is an argument against using a fully polymorphic `Ptr a` value as an abstract pointer, but I don't see anything wrong with using `Ptr ()` values or fully polymorphic `Ptr a` function arguments for that purpose. With any such low-level code, you have to trust the programmer to get things right anyway; replacing `Ptr ()` values by `Addr` values isn't going to make a big difference.
We would like it more often than not to be truthful. Yes, in the underlying C, there exists suboptimal typing, but that is why we are not writing in C, and instead lifting the code to Haskell.
We should also discuss the cost associated with mixing two functionally equivalent types in the same library, which will make the API less predictable, are likely to result in duplication in the APIs for Ptr and Addr, and will lead to more explicit type conversions with little benefit. And of course there is a risk of breaking existing code as existing API is changed to use the new type. (The term "user-facing" has popped up in this thread -- what does that mean in the case of such a low-level API?) Cheers, Bertram