Function Hooks

The Binding Generator C->Haskell : Implementation of Haskell Binding Modules : Function Hooks
Previous: Call Hooks
Next: Get Hooks

## 2.7. Function Hooks

> `{#fun [pure] [unsafe] cid [as (hsid | ^)] [ctxt =>] { parm1 , ... , parmn } -> parm`

Function hooks are call hooks including parameter marshalling. Thus, the components of a function hook up to and including the `as` alias are the same as for call hooks. However, an `as` alias has a different meaning; it specifies the name of the generated Haskell function. The remaining components use literals enclosed in backwards and foward single quotes (``` and `'`) to denote Haskell code fragments (or more precisely, parts of the Haskell type signature for the bound function). The first one is the phrase ctxt preceding `=>`, which denotes the type context. This is followed by zero or more type and marshalling specifications parm1 to parmn for the function arguments and one parm for the function result. Each such specification parm has the form

> `[inmarsh [* | -]] hsty [&] [outmarsh [*] [-]]`

where hsty is a Haskell code fragment denoting a Haskell type. The optional information to the left and right of this type determines the marshalling of the corresponding Haskell value to and from C; they are called the in and out marshaller, respectively.

Each marshalling specification parm corresponds to one or two arguments of the C function, in the order in which they are given. A marshalling specification in which the symbol `&` follows the Haskell type corresponds to two C function arguments; otherwise, it corresponds only to one argument. The parm following the left arrow `->` determines the marshalling of the result of the C function and may not contain the symbol `&`.

The `*-` output marshal specification is for monadic actions that must be executed but whose results are discarded. This is very useful for e.g. checking an error value and throwing an exception if needed.

Both inmarsh and outmarsh are identifiers of Haskell marshalling functions. By default they are assumed to be pure functions; if they have to be executed in the `IO` monad, the function name needs to be followed by a star symbol `*`. Alternatively, the identifier may be followed by a minux sign `-`, in which case the Haskell type does not appear as an argument (in marshaller) or result (out marshaller) of the generated Haskell function. In other words, the argument types of the Haskell function is determined by the set of all marshalling specifications where the in marshaller is not followed by a minus sign. Conversely, the result tuple of the Haskell function is determined by the set of all marshalling specifications where the out marshaller is not followed by a minus sign. The order of function arguments and components in the result tuple is the same as the order in which the marshalling specifications are given, with the exception that the value of the result marshaller is always the first component in the result tuple if it is included at all.

For a set of commonly occuring Haskell and C type combinations, default marshallers are provided by C->Haskell if no explicit marshaller is given. The out marshaller for function arguments is by default `void-`. The defaults for the in marshallers for function arguments are as follows:

- `Bool` and integral C type (including chars): `cFromBool`
- Integral Haskell and integral C type: `cIntConv`
- Floating Haskell and floating C type: `cFloatConv`
- `String` and `char*`: `withCString*`
- `String` and `char*` with explicit length: `withCStringLen*`
- T and T`*`: `with*`
- T and T`*` where T is an integral type: `withIntConv*`
- T and T`*` where T is a floating type: `withFloatConv*`
- `Bool` and T`*` where T is an integral type: `withFromBool*`

The defaults for the out marshaller of the result are the converse of the above; i.e., instead of the `with` functions, the corresponding `peek` functions are used. Moreover, when the Haskell type is `()`, the default marshaller is `void-`.

As an example, consider

> `

>     {#fun notebook_query_tab_label_packing as ^
>       `(NotebookClass nb, WidgetClass cld)' =>
>       {notebook `nb'                ,
>        widget   `cld'               ,
>        alloca-  `Bool'     peekBool*,
>        alloca-  `Bool'     peekBool*,
>        alloca-  `PackType' peekEnum*} -> `()'#}

> `

which results in the Haskell type signature

> `

>     notebookQueryTabLabelPacking :: (NotebookClass nb, WidgetClass cld)
>     			     => nb -> cld -> IO (Bool, Bool, PackType)

> `

which binds the following C function:

> `

>     void gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
>     					   GtkWidget   *child,
>     					   gboolean    *expand,
>     					   gboolean    *fill,
>     					   GtkPackType *pack_type);

> `

The Binding Generator C->Haskell : Implementation of Haskell Binding Modules : Function Hooks
Previous: Call Hooks
Next: Get Hooks