--- ^ A value of type @'FunPtr' a@ is a pointer to a piece of code. It
--- may be the pointer to a C function or to a Haskell function created
--- using @foreign export dynamic@. A @foreign export
--- dynamic@ should normally be declared to produce a
--- 'FunPtr' of the correct type. For example:
+-- ^ A value of type @'FunPtr' a@ is a pointer to a function callable
+-- from foreign code. The type @a@ will normally be a /foreign type/,
+-- a function type with zero or more arguments where
+--
+-- * the argument types are /marshallable foreign types/,
+-- i.e. 'Char', 'Int', 'Double', 'Float',
+-- 'Bool', 'Data.Int.Int8', 'Data.Int.Int16', 'Data.Int.Int32',
+-- 'Data.Int.Int64', 'Data.Word.Word8', 'Data.Word.Word16',
+-- 'Data.Word.Word32', 'Data.Word.Word64', @'Ptr' a@, @'FunPtr' a@,
+-- @'Foreign.StablePtr.StablePtr' a@ or a renaming of any of these
+-- using @newtype@.
+--
+-- * the return type is either a marshallable foreign type or has the form
+-- @'IO' t@ where @t@ is a marshallable foreign type or @()@.
+--
+-- A value of type @'FunPtr' a@ may be a pointer to a foreign function,
+-- either returned by another foreign function or imported with a
+-- a static address import like
+--
+-- > foreign import ccall "stdlib.h &free"
+-- > p_free :: FunPtr (Ptr a -> IO ())
+--
+-- or a pointer to a Haskell function created using a /wrapper/ stub
+-- declared to produce a 'FunPtr' of the correct type. For example: