haskell / c2hs

c2hs is a pre-processor for Haskell FFI bindings to C libraries
http://hackage.haskell.org/package/c2hs
Other
199 stars 50 forks source link

`{#pointer … newtype#}` vs. `{#pointer … foreign newtype#}` Type Correspondences #212

Open georgewsinger opened 6 years ago

georgewsinger commented 6 years ago

I have some conceptual questions about how C2HS generates type correspondences from {#pointer …} declarations. First, let ~ denote a type correspondence operator between C types and Haskell types. Then is it correct to say that

{#pointer *CTypeName as HaskellName newtype#}

generates the correspondence *CTypeName ~ HaskellName, while

{#pointer *CTypeName as HaskellName foreign newtype#}

generates the correspondence *CTypeName ~ (Ptr HaskellName)? (If so, does this imply in the latter case that CTypeName ~ HaskellName also?)

This is despite the fact that C2HS generates slightly different type definitions for each of the different declarations:

-- {#pointer *CTypeName as HaskellName newtype#}
data HaskellName = HaskellName (Ptr HaskellName)

-- {#pointer *CTypeName as HaskellName foreign newtype#}
data HaskellName = HaskellName (ForeignPtr HaskellName)

The ~ correspondences I mentioned above are somehow enforced by GHC/C2HS in the background, and they are only used to make foreign import … FFI declarations more type safe. If instead of writing {#pointer ...} declarations, we wrote instead their generated data HaskellName .. declarations as above (i.e., not using C2HS), then the C-to-Haskell type associations wouldn't be enforced by GHC natively (I'm assuming).

Finally, if we delete the * character in the {#pointer …} declarations above, then instead of us having type correspondences between *CTypeName ~ HaskellName and *CTypeName ~ (Ptr HaskellName), we would have type correspondences between CTypeName ~ HaskellName and CTypeName ~ (Ptr HaskellName).

Is all of my understanding correct?