So far we've provided the Haskell programmer with ways of importing
external functions into the Haskell world. The other half of the FFI
coin is how to expose Haskell functionality to the outside world. So,
dual to the foreign import declaration is foreign export:
topdecl
: ...
..
| 'foreign' 'export' callconv [ext_name] varid :: prim_type
A foreign export declaration tells the compiler to expose a
locally defined Haskell function to the outside world, i.e., wrap
it up behind a calling interface that's useable from C. It is only
permitted at the toplevel, where you have to specify the type at
which you want to export the function, along with the calling
convention to use. For instance, the following export declaration:
foreign export ccall "foo" bar :: Int -> Addr -> IO Double
will cause a Haskell system to generate the following C callable function:
HsDouble foo(HsInt arg1, HsAddr arg2);
When invoked, it will call the Haskell function bar, passing
it the two arguments that was passed to foo().
varid has got a prim_type.foreign export declaration is compatible with the type given to
function definition itself. The type in the foreign export may
be less general than that of the function itself. For example,
this is legal:
f :: Num a => a -> a
foreign export ccall "fInt" f :: Int -> Int
foreign export ccall "fFloat" f :: Float -> Float
These declarations export two C-callable procedures fInt and
fFloat, both of which are implemented by the (overloaded)
Haskell function f.
foreign exported IO action must catch all exceptions, as
the FFI does not address how to signal Haskell exceptions to the
outside world.