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?