Commit 72759510 authored by POTTIER Francois's avatar POTTIER Francois

Documented [@build].

parent 7527f247
...@@ -1092,6 +1092,7 @@ from \oc|VisitorsRuntime|. This is done via the \nude parameter ...@@ -1092,6 +1092,7 @@ from \oc|VisitorsRuntime|. This is done via the \nude parameter
% ------------------------------------------------------------------------------ % ------------------------------------------------------------------------------
\subsection{Generating visitors for preexisting types} \subsection{Generating visitors for preexisting types}
\label{sec:import}
Because the \derivingvisitors annotation must be attached to the type Because the \derivingvisitors annotation must be attached to the type
definition, it may seem as if it is impossible to generate a visitor for a definition, it may seem as if it is impossible to generate a visitor for a
...@@ -2242,6 +2243,67 @@ If desired, instead of \oc|[@name]|, one can use ...@@ -2242,6 +2243,67 @@ If desired, instead of \oc|[@name]|, one can use
% ------------------------------------------------------------------------------ % ------------------------------------------------------------------------------
\subsection{Alternate construction code in \map visitors}
\label{sec:build}
By default, a \map visitor for an algebraic data type constructs a new data
structure, by applying a data constructor or by allocating a new record.
Sometimes, though, it is illegal to do so: this is the case, for instance, if
the type has been declared \oc|private|.
%
% Sometimes, the default behavior is well-typed, but is not the desired
% behavior. In that case, it can be customized by overriding a method. Using
% [@build] offers a little extra conciseness and efficiency in that case, but
% this need not be advertised.
%
% Another solution would be to just write the visitor by hand for a private
% type, but that would require more work from the user.
%
In such a situation, an alternate constructor can be provided via a
\oc|[@build]| attribute (which must be attached to a data constructor) or via a
\oc|[@@build]| attribute (which must be attached to a record type declaration).
%
Such an attribute carries an OCaml expression, which should represent a
constructor function.
For instance, suppose that the module \oc|Point| has the following signature:
\begin{mdframed}[backgroundcolor=green!10]
\lstinputlisting{point.mli}
\end{mdframed}
Suppose that, outside of this module, one wishes to generate a \map visitor
for the type \oc|Point.point|. One would like to do this in the style that was
presented earlier (\sref{sec:import}), but a naïve attempt fails: the
generated visitor is illegal, because allocating a record of type
\oc|Point.point| is forbidden. To circumvent this problem, one should
indicate, via a \oc|[@@build]| attribute, that the constructor function
\oc|Point.make| should be used:
%
\begin{origenv}
\begin{lstlisting}
type point = Point.point = private { x: int; y: int }
[@@build Point.make]
[@@deriving visitors { variety = "map" }]
\end{lstlisting}
\end{origenv}
%
The OCaml expression carried by a \oc|[@build]| attribute can refer to the
local variable \oc|self|, which represents the visitor object, and to the
local variable \oc|env|, which represents the environment received by the
visitor method.
\oc|[@build]| attributes influence not only \map visitors,
but also \mapendo and \mapreduce visitors.
Instead of \oc|[@build]|, one can use
\oc|[@visitors.build]| or \oc|[@deriving.visitors.build]|.
% Be careful not to misspell the attribute name,
% as the attribute would then be silently ignored.
% ------------------------------------------------------------------------------
\bibliographystyle{plain} \bibliographystyle{plain}
\bibliography{english,local} \bibliography{english,local}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment