Alastair Reid wrote:
[...] Incidentally, how am I to interpret the type rules? Which of the following have the right type:
foreign import ccall "dynamic" mkFun1 :: FunPtr (Int -> IO ()) -> (Int -> IO ())
type Int2 = Int foreign import ccall "dynamic" mkFun2 :: FunPtr (Int2 -> IO ()) -> (Int -> IO ())
newtype Int3 = Int3 Int foreign import ccall "dynamic" mkFun3 :: FunPtr (Int3 -> IO ()) -> (Int -> IO ())
data Int4 = Int4 Int foreign import ccall "dynamic" mkFun4 :: FunPtr (Int4 -> IO ()) -> (Int -> IO ())
type T5 = FunPtr (Int -> IO ()) -> (Int -> IO ()) foreign import ccall "dynamic" mkFun5 :: T5
From the top of my head, the following should be correct: * mkFun1: Well, if *that* one isn't... :-) * mkFun2, mkFun5: The FFI should "look through" type synonyms (as usual) * mkFun3: The FFI should "look through" newtypes (for convenience) Wrong: * mkFun4: The FFI does not "look through" data, even in this easy case. (Hmmmm, but the current GHC from CVS allows this...)
[...] castStablePtrToPtr and castPtrToStablePtr can break typesafety so one might want to try to make sure that any program that uses them will be forced to have the word 'unsafe' in them.
The consensus was that every program which uses the FFI is inherently unsafe, so this is not a special problem of the casts. We dropped the 'unsafe' prefix consciously, IIRC.
Table 2 (section 6):
Is there a reason to be so coy about the concrete C types used for HsChar, HsFloat, HsDouble and HsBool?
Yes: The diversity of representations in the current Haskell implementations. I remember dozens of outcries overtime I wanted to be a little bit more specific in the first drafts of this table...
[...] HsChar Char unsigned char
Uh, oh! I'll die with a sudden heart attack... (And Marcin probably too :-} In a nutshell: Haskell Chars are supposed to be Unicode characters, Unicode is even larger than 16bit nowadays, and wchar_t is hopelessly underspecified. I'm not aware of any usable and portable C type for this, uint32_t is coming close, but is a bit misleading.
HsFloat Float float HsDouble Double double
A Haskell implementation could choose to use "double" for "Float" and "long double" for Double, or "float" for everything, or ...
HsBool Bool int
I see no reason at all not to specify HsBool.
Hmmm, I can't remember the reasoning for this vagueness.
[...] Table 3 (section 6):
Proposed change:
Rename column 1 as 'Preprocessor symbol'.
In the last 2 lines, change column 1 to read HS_BOOL_FALSE and HS_BOOL_TRUE. (This change merely standardizes the existing GHC fix for this problem.)
I agree to both change. Cheers, S.