Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <chessai1996@gmail.com>:
'Ptr Void' is not a pointer to a value of type 'Void'; there are no values of type 'Void': this type is nonsensical.

That's the whole point, and it actually makes sense: If you see "Ptr Void", you can't do much with it, apart from passing it around or using castPtr on it. This is exactly what should be achieved by using "Ptr Void" in an API. This is basically the same as "void *" in C/C++.
 
'Ptr a' is not a pointer to a value of type a; what is 'a'?

As usual, it's the "I don't care about it" type. :) Take e.g. mallocBytes: It returns a "Ptr a" exactly because of the fact that it doesn't care about what will eventually be stored in the new area. Another API design option would have been returning "Ptr Void" or "Ptr ()" instead, but this would have forced API users to insert castPtr, which is only annoying there and wouldn't buy us a single bit of security in those circumstances.
 
'Ptr ()' could be a pointer to a value of type '()', and if so, then this is a correct usage of 'Ptr'. If not, it is an incorrect usage of 'Ptr'.

You can't store or read "()", so the same holds as for Void (which didn't exist when the FFI was created IIRC).