Special Structures

This section describes the SML structures that are not generated by introspection, or deviate significantly from their introspected form.

Giraffe

The top-level structure Giraffe provides general purpose utilities. Currently, the structure provides functions for exiting an application that are more convenient than the Basis Library alternatives.

structure Giraffe :> GIRAFFE
signature GIRAFFE =
  sig
    (**
     * `exit status` exits the process where the exit status is the lower
     *  8 bits of (the two's complement representation of) `status`.
     *)
    val exit : LargeInt.int -> 'a

    (**
     * `error status errMsgs` outputs `errMsgs` to the standard error,
     * flushes the standard error and exits the process using `exit status`.
     *)
    val error : LargeInt.int -> string list -> 'a
  end

ValueAccessor

This structure is unlikely to be needed by an application because there is rarely a need to use a GObject.Value instance directly, especially as the structure Property provides a high-level type safe interface for properties.

The top-level structure ValueAccessor is included with the structure GObject and provides support for working with GObject.Value records directly. The structure defines the type 'a ValueAccessor.t that encapsulates typed access to a GObject.Value record. This does not provide type safe access to a GObject.Value record but each accessor links an SML type and GObject dynamic type (represented by GObject.Type) allowing type-safe wrappers to be created around a GObject.Value record.

structure ValueAccessor :>
  VALUE_ACCESSOR
    where type type_t = GObjectType.t
    where type value_t = GObjectValueRecord.t
    where type C.value_v = GObjectValueRecord.C.v
signature VALUE_ACCESSOR =
  sig
    type 'a t

    type type_t
    type value_t

    val new : 'a t -> 'a -> value_t
    val get : 'a t -> value_t -> 'a
    val set : 'a t -> value_t -> 'a -> unit
    val gtype : 'a t -> type_t

    val map : ('a -> 'b) * ('b -> 'a) -> 'a t -> 'b t

    structure C :
      sig
        type value_v

        val createAccessor :
          {
            getType  : unit -> type_t,
            getValue : value_v -> 'a,
            setValue : (value_v, 'a) pair -> unit
          }
           -> 'a t

        val gtype : 'a t -> unit -> type_t
        val get : 'a t -> value_v -> 'a
        val set : 'a t -> value_v -> 'a -> unit

        val init : value_v -> type_t -> unit

        val isValue : value_v -> bool
      end

    structure Types :
      sig
        val boolean : bool t
        val int : LargeInt.int t
        val uint : LargeInt.int t
        val long : LargeInt.int t
        val ulong : LargeInt.int t
        val int64 : LargeInt.int t
        val uint64 : LargeInt.int t
        val float : real t
        val double : real t
        val char : char t
        val string : string t
        val stringOpt : string option t
      end
  end

Signal

The top-level structure Signal is included with the structure GObject and provides a high-level type safe representation of a signal, ('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) Signal.t, and associated operations.

The internal representation of type Signal.t is exposed to work around the value restriction when declaring a signal value. (A parameter of type Signal.t always contains a variable.) Typically, applications do not declare signals so the internal representation can be ignored.

structure Signal :>
  SIGNAL
    where type 'a object_class = 'a GObjectObjectClass.class
    where type ('object_class, 'get, 'set, 'init) property_t =
            ('object_class, 'get, 'set, 'init) Property.t
    where type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller =
            ('arg_r, 'arg_w, 'res_r, 'res_w) GObjectClosure.marshaller
signature SIGNAL =
  sig
    type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller

    (**
     * Representation of a signal
     *
     * The type `('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t`
     * represents a signal of the class represented by the type
     * `'object_class` where
     *
     *     'arg_e -> 'res_e
     *       is the type of a function that emits the signal and
     *
     *     'arg_h -> 'res_h
     *       is the type of a function that handles the signal.
     *
     * The type parameters `'arg_e`, `'arg_h`, `'res_h` and `'res_e` capture
     * the type and direction of the signal arguments and the type of the
     * signal return value as follows:
     *
     *     `'arg_e` and `'arg_h` are instantiated to the types of the
     *       signal 'in' and 'inout' arguments;
     *
     *     `'res_e` and `'res_h` are instantiated to the types of the
     *       signal return value and 'out' and 'inout' arguments.
     *
     * The 'e' and 'h' variants differ in whether they allow an object of any
     * subclass or not and whether they allow an instance of any field of a
     * union or not.
     *
     * Ideally, the type `('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t`
     * would be abstract and a function defined to construct values of the
     * type.  However, the resulting value always contains a type variable in
     * the parameter `'object_class` to allow the type of any subclass to
     * unify with it.  The application of the construction function is a non-
     * expansive expression so the result cannot be a value containing a
     * type variable due to the value restriction.  The usual work around
     * for the value restriction is to defer evaluation, so a signal would
     * have the type `unit -> ('object_class, ...) t` but this is not done.
     * Instead, the type is not abstract and its concrete representation - a
     * record - enables a value to be written as an expansive expression,
     * thereby avoiding the value restriction.
     *)
    type ('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t =
      {
        name       : string,
        detail     : string,
        marshaller :
          unit
           -> (
                (unit,          'arg_h) pair,
                ('object_class, 'arg_e) pair,
                'res_e,
                'res_h
              )
               marshaller
      }

    val conv :
      ('a -> 'b)
       -> ('b, 'arg_e, 'arg_h, 'res_h, 'res_e) t
       -> ('a, 'arg_e, 'arg_h, 'res_h, 'res_e) t

    type 'a object_class

    val emit :
      'a object_class
       -> ('a object_class, 'arg_e, 'b, 'c, 'res_e) t
       -> 'arg_e -> 'res_e

    type handler_id
    val connect :
      'a object_class
       -> ('a object_class, 'b, 'arg_h, 'res_h, 'c) t * ('arg_h -> 'res_h)
       -> handler_id
    val connectAfter :
      'a object_class
       -> ('a object_class, 'b, 'arg_h, 'res_h, 'c) t * ('arg_h -> 'res_h)
       -> handler_id
    val handlerBlock   : 'a object_class -> handler_id -> unit
    val handlerUnblock : 'a object_class -> handler_id -> unit
    val handlerDisconnect : 'a object_class -> handler_id -> unit
    val handlerIsConnected : 'a object_class -> handler_id -> bool

    val detail : ('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t -> string
    val withDetail :
      ('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t * string
       -> ('object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t

    type ('object_class, 'get, 'set, 'init) property_t
    val withPropDetail :
      ('a object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t
           * ('a object_class, 'get, 'set, 'init) property_t
       -> ('a object_class, 'arg_e, 'arg_h, 'res_h, 'res_e) t
  end

ChildSignal

The top-level structure ChildSignal is included with the structure Gtk and provides convenience functions that connect a handler to a signal of a non Gtk.Widget object where the handler is disconnected when a Gtk.Widget object receives the “destroy” signal.

This is intended to be used for connecting a handler to a signal of an object where the handler function directly or indirectly references the object. In this scenario, there is a reference cycle that is not visible to the SML compiler's garbage collector. There is no issue for a signal of a Gtk.Widget object because the “destroy” signal causes any signal handlers to be disconnected. For a non Gtk.Widget object, which does not have a “destroy” signal, the signal handler must be explicitly disconnected to remove the reference cycle. The functions in this structure simplify this when there is a widget whose lifespan can be used as the lifespan of the handler function (and there typically is such a widget).

structure ChildSignal :>
  CHILD_SIGNAL
    where type 'a widget_class = 'a GtkWidgetClass.class
signature CHILD_SIGNAL =
  sig
    type 'a widget_class

    val connect :
      'a widget_class
       -> 'b GObject.ObjectClass.class
       -> ('b GObject.ObjectClass.class, 'c, 'arg_h, 'res_h, 'd) Signal.t * ('arg_h -> 'res_h)
       -> unit
    val connectAfter :
      'a widget_class
       -> 'b GObject.ObjectClass.class
       -> ('b GObject.ObjectClass.class, 'c, 'arg_h, 'res_h, 'd) Signal.t * ('arg_h -> 'res_h)
       -> unit
  end

Property

The top-level structure Property is included with the structure GObject and provides a high-level type safe representation of a property, ('object_class, 'get, 'set, 'init) Property.t, and associated operations.

structure Property :>
  PROPERTY
    where type type_t = GObjectType.t
    where type value_v = GObjectValueRecord.C.v
    where type 'a object_class = 'a GObjectObjectClass.class
    where type 'a binding_class = 'a GObjectBindingClass.class
signature PROPERTY =
  sig
    type type_t
    type value_v
    type 'a object_class
    type 'a binding_class

    (**
     * Representation of a property
     *
     * The type `('object_class, 'get, 'set, 'init) t` represents a property
     * of an object whose class is represented by the type `'object_class`.
     * The type parameters `'get`, `'set` and `'init` capture the possible
     * access modes as follows so that type checking ensures mode safety:
     *
     *     'get is instantiated to:
     *
     *         unit -> 'r
     *           if a value of type 'r can be read from the property
     *
     *         unit
     *           if the property is not readable
     *
     *     'set is instantiated to:
     *
     *         'w -> unit
     *           if a value of type 'w can be written to the property
     *           after object construction
     *
     *         unit
     *           if the property is not writable after object construction
     *
     *     'init is instantiated as for 'set but according to whether
     *     a value of type 'w can be set during object construction.
     *
     * Ideally, the type `('object_class, 'get, 'set, 'init) t` would be
     * abstract and a function defined to construct values of the type.
     * However, the resulting value always contains a type variable in the
     * parameter `'object_class` to allow the type of any subclass to unify
     * with it.  The application of the construction function is a non-
     * expansive expression so the result cannot be a value containing a
     * type variable due to the value restriction.  The usual work around
     * for the value restriction is to defer evaluation, so a property would
     * have the type `unit -> ('object_class, 'get, 'set, 'init) t` but this
     * is not done.  Instead, the type is not abstract and its concrete
     * representation - a record - enables a value to be written as an
     * expansive expression, thereby avoiding the value restriction.
     * However, the type parameter `'object_class` is a phantom type which
     * must be therefore be mentioned in the concrete representation
     * (otherwise it imposes no type constraint).  An argument of this
     * type can be added to the `get` and `set` functions because they
     * require an object instance to operate on therefore there is always
     * a value available to use as the witness for the type.  Note that the
     * field `gtype` must defer evaluation because some GObject types are not
     * determined until run-time.  This is convenient because it allows the
     * value to be defined by a non-expansive expression without falling foul
     * of the value restriction.
     *)
    type ('object_class, 'get, 'set, 'init) t =
      {
        name  : string,
        gtype : unit -> type_t,
        get   : 'object_class -> value_v -> 'get,
        set   : 'object_class -> value_v -> 'set,
        init  :                  value_v -> 'init
      }

    val conv :
      ('a -> 'b)
       -> ('b, 'get, 'set, 'init) t
       -> ('a, 'get, 'set, 'init) t

    (**
     * Access to a property
     *)
    val get : ('a object_class, unit -> 'r, 'b, 'c) t -> 'a object_class -> 'r
    val set : ('a object_class, 'b, 'w -> unit, 'c) t -> 'w -> 'a object_class -> unit

    (**
     * Initial value of a property, for use with `GObject.Object.new`
     *)
    type 'object_class init_t
    val init : ('object_class, 'a, 'b, 'w -> unit) t -> 'w -> 'object_class init_t
    val initName : 'object_class init_t -> string
    val initValue : 'object_class init_t -> value_v -> unit

    (**
     * Binding two properties
     *
     * These functions provide a type safe interface to
     * `GObject.Object.bindProperty[Full]`.  For the non-full versions, where
     * the conversion is implicit, it is assumed that if two properties have
     * the same SML type but different GObject types, then the value of one
     * can be transformed to the value of the other.
     *
     * In every function, the `bool` argument determines whether the
     * properties are synchronized on creation.
     *)
    val bind :
      'a object_class
       * ('a object_class, unit -> 'c, 'set, 'init) t
       * 'b object_class
       * ('b object_class, 'get, 'c -> unit, 'init) t
       * bool
       -> base binding_class
    val bindBidir :
      'a object_class
       * ('a object_class, unit -> 'c, 'd -> unit, 'init) t
       * 'b object_class
       * ('b object_class, unit -> 'd, 'c -> unit, 'init) t
       * bool
       -> base binding_class
    val bindInvertBool :
      'a object_class
       * ('a object_class, unit -> bool, 'set, 'init) t
       * 'b object_class
       * ('b object_class, 'get, bool -> unit, 'init) t
       * bool
       -> base binding_class
    val bindBidirInvertBool :
      'a object_class
       * ('a object_class, unit -> bool, bool -> unit, 'init) t
       * 'b object_class
       * ('b object_class, unit -> bool, bool -> unit, 'init) t
       * bool
       -> base binding_class
    val bindFull :
      'a object_class
       * ('a object_class, unit -> 'c, 'set, 'init) t
       * 'b object_class
       * ('b object_class, 'get, 'd -> unit, 'init) t
       * bool
       * ('c -> 'd)
       -> base binding_class
    val bindFullBidir :
      'a object_class
       * ('a object_class, unit -> 'c, 'f -> unit, 'init) t
       * 'b object_class
       * ('b object_class, unit -> 'e, 'd -> unit, 'init) t
       * bool
       * ('c -> 'd)
       * ('e -> 'f)
       -> base binding_class
  end

ClassifyEvent

The top-level structure ClassifyEvent is included with the structure Gdk and provides a data type ClassifyEvent.t and a function ClassifyEvent.classify to return the current field of a Gdk.Event union according to its discriminant.

structure ClassifyEvent :>
  CLASSIFY_EVENT
    where type 'a event_union = 'a GdkEvent.union
    where type event_any_t = GdkEventAnyRecord.t
    where type event_key_t = GdkEventKeyRecord.t
    where type event_button_t = GdkEventButtonRecord.t
    where type event_scroll_t = GdkEventScrollRecord.t
    where type event_motion_t = GdkEventMotionRecord.t
    where type event_expose_t = GdkEventExposeRecord.t
    where type event_visibility_t = GdkEventVisibilityRecord.t
    where type event_crossing_t = GdkEventCrossingRecord.t
    where type event_focus_t = GdkEventFocusRecord.t
    where type event_configure_t = GdkEventConfigureRecord.t
    where type event_property_t = GdkEventPropertyRecord.t
    where type event_selection_t = GdkEventSelectionRecord.t
    where type event_dnd_t = GdkEventDNDRecord.t
    where type event_proximity_t = GdkEventProximityRecord.t
    where type event_window_state_t = GdkEventWindowStateRecord.t
    where type event_setting_t = GdkEventSettingRecord.t
    where type event_owner_change_t = GdkEventOwnerChangeRecord.t
    where type event_grab_broken_t = GdkEventGrabBrokenRecord.t
    where type event_any_record_event = GdkEventAnyRecord.event
    where type event_key_record_event = GdkEventKeyRecord.event
    where type event_button_record_event = GdkEventButtonRecord.event
    where type event_scroll_record_event = GdkEventScrollRecord.event
    where type event_motion_record_event = GdkEventMotionRecord.event
    where type event_expose_record_event = GdkEventExposeRecord.event
    where type event_visibility_record_event = GdkEventVisibilityRecord.event
    where type event_crossing_record_event = GdkEventCrossingRecord.event
    where type event_focus_record_event = GdkEventFocusRecord.event
    where type event_configure_record_event = GdkEventConfigureRecord.event
    where type event_property_record_event = GdkEventPropertyRecord.event
    where type event_selection_record_event = GdkEventSelectionRecord.event
    where type event_dnd_record_event = GdkEventDNDRecord.event
    where type event_proximity_record_event = GdkEventProximityRecord.event
    where type event_window_state_record_event = GdkEventWindowStateRecord.event
    where type event_setting_record_event = GdkEventSettingRecord.event
    where type event_owner_change_record_event = GdkEventOwnerChangeRecord.event
    where type event_grab_broken_record_event = GdkEventGrabBrokenRecord.event
signature CLASSIFY_EVENT =
  sig
    type 'a event_union

    type event_any_t
    type event_key_t
    type event_button_t
    type event_touch_t
    type event_scroll_t
    type event_motion_t
    type event_expose_t
    type event_visibility_t
    type event_crossing_t
    type event_focus_t
    type event_configure_t
    type event_property_t
    type event_selection_t
    type event_dnd_t
    type event_proximity_t
    type event_window_state_t
    type event_setting_t
    type event_owner_change_t
    type event_grab_broken_t
    type event_touchpad_swipe_t
    type event_touchpad_pinch_t
    type event_pad_button_t
    type event_pad_axis_t
    type event_pad_group_mode_t

    type event_any_record_event
    type event_key_record_event
    type event_button_record_event
    type event_touch_record_event
    type event_scroll_record_event
    type event_motion_record_event
    type event_expose_record_event
    type event_visibility_record_event
    type event_crossing_record_event
    type event_focus_record_event
    type event_configure_record_event
    type event_property_record_event
    type event_selection_record_event
    type event_dnd_record_event
    type event_proximity_record_event
    type event_window_state_record_event
    type event_setting_record_event
    type event_owner_change_record_event
    type event_grab_broken_record_event
    type event_touchpad_swipe_record_event
    type event_touchpad_pinch_record_event
    type event_pad_button_record_event
    type event_pad_axis_record_event
    type event_pad_group_mode_record_event

    datatype t =
      ANY            of event_any_t            * event_any_record_event
    | KEY            of event_key_t            * event_key_record_event
    | BUTTON         of event_button_t         * event_button_record_event
    | TOUCH          of event_touch_t          * event_touch_record_event
    | SCROLL         of event_scroll_t         * event_scroll_record_event
    | MOTION         of event_motion_t         * event_motion_record_event
    | EXPOSE         of event_expose_t         * event_expose_record_event
    | VISIBILITY     of event_visibility_t     * event_visibility_record_event
    | CROSSING       of event_crossing_t       * event_crossing_record_event
    | FOCUS          of event_focus_t          * event_focus_record_event
    | CONFIGURE      of event_configure_t      * event_configure_record_event
    | PROPERTY       of event_property_t       * event_property_record_event
    | SELECTION      of event_selection_t      * event_selection_record_event
    | DND            of event_dnd_t            * event_dnd_record_event
    | PROXIMITY      of event_proximity_t      * event_proximity_record_event
    | WINDOW_STATE   of event_window_state_t   * event_window_state_record_event
    | SETTING        of event_setting_t        * event_setting_record_event
    | OWNER_CHANGE   of event_owner_change_t   * event_owner_change_record_event
    | GRAB_BROKEN    of event_grab_broken_t    * event_grab_broken_record_event
    | TOUCHPAD_SWIPE of event_touchpad_swipe_t * event_touchpad_swipe_record_event
    | TOUCHPAD_PINCH of event_touchpad_pinch_t * event_touchpad_pinch_record_event
    | PAD_BUTTON     of event_pad_button_t     * event_pad_button_record_event
    | PAD_AXIS       of event_pad_axis_t       * event_pad_axis_record_event
    | PAD_GROUP_MODE of event_pad_group_mode_t * event_pad_group_mode_record_event

    val classify : 'a event_union -> t option
  end

Internal

The structures in this section should not be needed by applications but are listed for reference.

GObjectType

The top-level structure GObjectType provides the implementation of the GObject.Type structure. In the GObject namespace, introspection metadata defines the type named Type as an alias for gsize which would result in GObject.Type.t being equivalent to the type GSize.t. This structure makes GObject.Type.t an abstract scalar equality type to prevent use as an integer and provides operations and constructors for this type.

structure GObjectType :> G_OBJECT_TYPE
signature G_OBJECT_TYPE =
  sig
    include C_SCALAR_EQ_NULL

    val isValueType : t -> bool
    val isA : t * t -> bool
    val name : t -> string
    val fromName : string -> t option

    val invalid         : unit -> t
    val none            : unit -> t
    val interface       : unit -> t
    val char            : unit -> t
    val uchar           : unit -> t
    val boolean         : unit -> t
    val int             : unit -> t
    val uint            : unit -> t
    val long            : unit -> t
    val ulong           : unit -> t
    val int64           : unit -> t
    val uint64          : unit -> t
    val enum            : unit -> t
    val flags           : unit -> t
    val float           : unit -> t
    val double          : unit -> t
    val string          : unit -> t
    val pointer         : unit -> t
    val boxed           : unit -> t
    val param           : unit -> t
    val object          : unit -> t
    val gtype           : unit -> t
    val variant         : unit -> t
    val paramChar       : unit -> t
    val paramUChar      : unit -> t
    val paramBoolean    : unit -> t
    val paramInt        : unit -> t
    val paramUInt       : unit -> t
    val paramLong       : unit -> t
    val paramULong      : unit -> t
    val paramInt64      : unit -> t
    val paramUInt64     : unit -> t
    val paramUnichar    : unit -> t
    val paramEnum       : unit -> t
    val paramFlags      : unit -> t
    val paramFloat      : unit -> t
    val paramDouble     : unit -> t
    val paramString     : unit -> t
    val paramParam      : unit -> t
    val paramBoxed      : unit -> t
    val paramPointer    : unit -> t
    val paramValueArray : unit -> t
    val paramObject     : unit -> t
    val paramOverride   : unit -> t
    val paramGType      : unit -> t
    val paramVariant    : unit -> t
  end

GObjectValue

The top-level structure GObjectValue provides the implementation of the GObject.Value structure. This structure excludes the introspected get and set functions because the ValueAccessor structure is used instead. Accessors for the fundamental types are provided in the structure ValueAccessor.Types.

The function GObjectValue.reset deviates from its introspected form by returning unit rather than its argument.

The function GObjectValue.new is provided in addition to the introspected functions.

structure GObjectValue :>
  G_OBJECT_VALUE
    where type t = GObjectValueRecord.t
    where type type_t = GObjectType.t
signature G_OBJECT_VALUE =
  sig
    type t
    type type_t
    val getType : unit -> type_t
    val new : unit -> t  (* new value is initialized to zero *)
    val copy :
      t
       -> t
       -> unit
    val fitsPointer : t -> bool
    val init :
      t
       -> type_t
       -> unit
    val reset : t -> unit
    val transform :
      t
       -> t
       -> bool
    val unset : t -> unit
    val typeCompatible : type_t * type_t -> bool
    val typeTransformable : type_t * type_t -> bool
    val holds : type_t -> t -> bool
    val gTypeOf : t -> type_t
    val isValue : t -> bool
  end

GObjectClosure

The top-level structure GObjectClosure provides the implementation of the GObject.Closure structure. This structure excludes most of the introspected entities and provides a constructor GObjectClosure.new that creates a GObject closure that wraps an SML function of type 'arg_r -> 'res_w given an SML marshaller of type ('arg_r, 'arg_w, 'res_r, 'res_w) ClosureMarshal.marshaller.

structure GObjectClosure :>
  G_OBJECT_CLOSURE
    where type t = GObjectClosureRecord.t
    where type type_t = GObjectType.t
    where type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller = ('arg_r, 'arg_w, 'res_r, 'res_w) ClosureMarshal.marshaller
signature G_OBJECT_CLOSURE =
  sig
    type t
    type type_t
    type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller
    val getType : unit -> type_t
    val new : ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller * ('arg_r -> 'res_w) -> t
    val invalidate : t -> unit
  end

ClosureMarshal

The top-level structure ClosureMarshal is included with the structure GObject and provides functions to construct an SML marshaller for a GObject closure. An SML marshaller is bidirectional: given an SML marshaller of type ('arg_r, 'arg_w, 'res_r, 'res_w) ClosureMarshal.marshaller, a GObject closure can be called by an SML function of type 'arg_w -> 'res_r and an SML function of type 'arg_r -> 'res_w can be called by a GObject closure.

structure ClosureMarshal :>
  CLOSURE_MARSHAL
    where type 'a accessor = 'a ValueAccessor.t
    where type C.value_v = GObjectValueRecord.C.v
    where type C.value_array_v = GObjectValueRecordCArrayN.C.non_opt GObjectValueRecordCArrayN.C.p
infixr &&&

signature CLOSURE_MARSHAL =
  sig
    type 'a accessor


    structure C :
      sig
        type value_v
        type value_array_v
      end

    type ('r, 'w) arg
    type ('r, 'w) res
    type ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller =
      {
        getArg   : C.value_array_v -> 'arg_r,
        setArg   : C.value_array_v -> 'arg_w -> unit,
        getRes   : C.value_array_v * C.value_v -> 'res_r,
        setRes   : C.value_array_v * C.value_v -> 'res_w -> unit,
        initPars : (C.value_v -> unit) vector,
        initRet  : C.value_v -> unit
      }

    val &&&> :
      ('a_r, 'a_w) arg * ('b_r, 'b_w) arg
       -> (('a_r, 'b_r) pair, ('a_w, 'b_w) pair) arg

    val &&& :
      ('a_r, 'a_w) res * ('b_r, 'b_w) res
       -> (('a_r, 'b_r) pair , ('a_w, 'b_w) pair) res

    val ---> :
      ('arg_r, 'arg_w) arg * ('res_r, 'res_w) res
       -> ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller

    val parInst :        'a accessor -> (unit, 'a) arg
    val parIn   : int -> 'a accessor -> ('a,   'a) arg
    val parOut  : int -> 'a accessor -> ('a,   'a)   res
    val ret     :        'a accessor -> ('a,   'a)   res
    val retVoid :                       (unit, unit) res

    val map :
      ('arg1_r -> 'arg2_r)
       * ('arg2_w -> 'arg1_w)
       * ('res1_r -> 'res2_r)
       * ('res2_w -> 'res1_w)
       -> ('arg1_r, 'arg1_w, 'res1_r, 'res1_w) marshaller
       -> ('arg2_r, 'arg2_w, 'res2_r, 'res2_w) marshaller

    type callback
    val makeCallback :
      ('arg_r, 'arg_w, 'res_r, 'res_w) marshaller * ('arg_r -> 'res_w)
       -> callback


    …
  end