The range of types that can be passed as arguments to an external function is restricted (as are the range of results coming back):
prim_type : IO prim_result
| prim_result
| prim_arg '->' prim_type
IOExts.unsafePerformIO in your Haskell programs.prim_type:
prim_type : ...
| unsafe_arr_ty '->' prim_type
unsafe_arr_ty : ByteArray a
| MutableByteArray i s a
GHC permits the passing of its byte array primitive types
to external functions. There's some restrictions on when
they can be used; see Section
Argument types
for more details.Section
Result type defines
prim_result; Section
Argument types
defines prim_arg.
The external function expects zero or more arguments. The set of legal argument types is restricted to the following set:
prim_arg : ext_ty | new_ty | ForeignObj
new_ty : a Haskell newtype of a prim_arg.
ext_ty : int_ty | word_ty | float_ty
| Addr | Char | StablePtr a
int_ty : Int | Int8 | Int16 | Int32 | Int64
word_ty : Word8 | Word16 | Word32 | Word64
float_ty : Float | Double
ext_ty represent the set of basic types supported by
C-like languages, although the numeric types are explicitly sized.
The stable pointer StablePtr type looks out of place in
this list of C-like types, but it has a well-defined and simple
C mapping, see Section
Type mapping
for details.
prim_arg represent the set of permissible argument types. In
addition to ext_ty, ForeignObj is also included.
The ForeignObj type represent values that are pointers to some
external entity/object. It differs from the Addr type in that
ForeignObjs are finalized, i.e., once the garbage collector
determines that a ForeignObj is unreachable, it will invoke a
finalising procedure attached to the ForeignObj to notify the
outside world that we're through with using it.
newtypes that wrap up a prim_arg type can also
be passed to external functions. foreign import declarations. Qualified names likewise,
i.e. Word.Word32 is legal.
foreign import does not support the binding to external
constants/variables. A foreign import declaration that takes no
arguments represent a binding to a function with no arguments.
prim_type : ...
| prim_arg '->' prim_type
| unsafe_arr_ty '->' prim_type
unsafe_arr_ty : ByteArray a
| MutableByteArray i s a
GHC's ByteArray and MutableByteArray primitive types are
(im)mutable chunks of memory allocated on the Haskell heap, and
pointers to these can be passed to foreign imported external
functions provided they are marked as unsafe. Since it is
inherently unsafe to hand out references to objects in the Haskell
heap if the external call may cause a garbage collection to happen,
you have to annotate the foreign import declaration with
the attribute unsafe. By doing so, the user explicitly states
that the external function won't provoke a garbage collection,
so passing out heap references to the external function is allright.
prim_arg : ... | unboxed_h_ty
ext_ty : .... | unboxed_ext_ty
unboxed_ext_ty : Int# | Word# | Char#
| Float# | Double# | Addr#
| StablePtr# a
unboxed_h_ty : MutableByteArray# | ForeignObj#
| ByteArray#
Clearly, if you want to be portable across Haskell systems, using
system-specific extensions such as this is not advisable; avoid
using them if you can. (Support for using unboxed types might
be withdrawn sometime in the future.)
An external function is permitted to return the following range of types:
prim_result : ext_ty | new_ext_ty | ()
new_ext_ty : a Haskell newtype of an ext_ty.
where () represents void / no result.
foreign import user to layer
any error handling on top of an external function.ext_ty) can be passed back, i.e., returning
ForeignObjs is not supported/allowed. ext_ty are also permitted.