@@ -106,110 +106,103 @@ module Std : sig
106106
107107 (* * Variadic arguments.
108108
109- [Variadic], abstracts a common idiom of a function applied to a
110- variable number of arguments. A common examples of such function
111- would be OCaml's standard [printf] and [scanf] functions. A more
112- general examples, are monadic parsers, such as [MParser],
113- command line parsers such as [Cmdliner] and [Core]'s
114- [Command]. They all are using the same trick to collect
115- arguments of different type and pass it to a function, s.t.
116- the function type actually defines the type of collected
117- arguments. Both [Cmdliner] and [Command] relies on [Applicative]
118- functor defined in [1]. However, it requires a [return]
119- function, that is not possible to provide in general for
120- co-inductive types, that can only be observed or mapped. It is
121- still possible to implement a variadic interface using the
122- restricted [Applicable] interface given only one restriction: it
123- is not possible to create an empty variadic list of arguments
124- (that can be considered as a benefit).
125-
126-
127- Here are some examples, that highlights common use cases of the
128- variadic structure. Suppose, we have several future values of
129- different types, that we would like to merge with some function
130- [f], to be concrete let's assume, that we're waiting for:
109+ [Variadic], abstracts a common idiom of a function applied to a variable
110+ number of arguments. A common examples of such function would be OCaml's
111+ standard [printf] and [scanf] functions. A more general examples, are
112+ monadic parsers, such as [MParser], command line parsers such as
113+ [Cmdliner] and [Core]'s [Command]. They all are using the same trick to
114+ collect arguments of different type and pass it to a function, s.t. the
115+ function type actually defines the type of collected arguments. Both
116+ [Cmdliner] and [Command] relies on [Applicative] functor defined in [1].
117+ However, it requires a [return] function, that is not possible to provide
118+ in general for co-inductive types, that can only be observed or mapped. It
119+ is still possible to implement a variadic interface using the restricted
120+ [Applicable] interface given only one restriction: it is not possible to
121+ create an empty variadic list of arguments (that can be considered as a
122+ benefit).
123+
124+ Here are some examples, that highlights common use cases of the variadic
125+ structure. Suppose, we have several future values of different types, that
126+ we would like to merge with some function [f], to be concrete let's
127+ assume, that we're waiting for:
131128
132129 [arch : arch future] - program architecture to be defined;
133- [lang : lang future] - a programming language;
134- [abi : abi future] - an ABI;
135- [api : api future] - an api specification
130+ [lang : lang future] - a programming language; [abi : abi future] - an
131+ ABI; [api : api future] - an api specification
136132
137133 And we have a function [typecheck] of type
138134
139- {[arch -> lang -> abi -> api -> pass future]},
135+ {[
136+ arch -> lang -> abi -> api -> pass future
137+ ]}
138+ ,
140139
141- that will typecheck a binary program, according to the typing
142- rules of the specified programming [lang]uage, binary interface,
143- and type environment [api]. Given the [Variadic] interface we
144- can write it as
140+ that will typecheck a binary program, according to the typing rules of the
141+ specified programming [lang]uage, binary interface, and type environment
142+ [api]. Given the [Variadic] interface we can write it as
145143
146- [Future.Variadic.(apply (args arch $lang $abi $api) ~f:typecheck]
144+ [Future.Variadic.(apply (args arch $lang $abi $api) ~f:typecheck) ]
147145
148- Note, since future implements a more powerful Monad interface,
149- it is still possible to apply a [typecheck] function without
150- using the variadic interface, e.g.,
146+ Note, since future implements a more powerful Monad interface, it is still
147+ possible to apply a [typecheck] function without using the variadic
148+ interface, e.g.,
151149
152150 {[
153151 arch >>= fun arch ->
154152 lang >>= fun lang ->
155153 abi >>= fun abi ->
156- api >>= fun api ->
157- typecheck arch lang abi api
154+ api >>= fun api -> typecheck arch lang abi api
158155 ]}
159156
160- However, this is less general, as it specifies a concrete order
161- of argument bindings, it is also requires a much less general
162- monad interface with bind and return operations, that are in
163- general not available for coinductive types, for example for
164- [stream ] type. If we substitute [future] type constructor in the
165- above example with a [stream] constructor we will no be able to
166- implement the latter solution, as we lack the monad interface.
157+ However, this is less general, as it specifies a concrete order of
158+ argument bindings, it is also requires a much less general monad interface
159+ with bind and return operations, that are in general not available for
160+ coinductive types, for example for [stream] type. If we substitute
161+ [future ] type constructor in the above example with a [stream] constructor
162+ we will no be able to implement the latter solution, as we lack the monad
163+ interface.
167164
168- Using a stream for this particular example, makes sense, since,
169- the specified properties, can be defined on a module level, so
170- they can be defined multiple times for each project. In that
171- case function typecheck will be applied for each quartet of the
172- arguments.
165+ Using a stream for this particular example, makes sense, since, the
166+ specified properties, can be defined on a module level, so they can be
167+ defined multiple times for each project. In that case function typecheck
168+ will be applied for each quartet of the arguments.
173169
174- When used with collections, such as list, sequences, sets, etc,
175- the pattern can be used to generalize cartesian product from a
176- function taking a pair of arguments, to a function taking
177- arbitrary amount of arguments.
170+ When used with collections, such as list, sequences, sets, etc, the
171+ pattern can be used to generalize cartesian product from a function taking
172+ a pair of arguments, to a function taking arbitrary amount of arguments.
178173
179- For collection, the Variadic can be used to generalize cartesian
180- product to [N] arguments:
174+ For collection, the Variadic can be used to generalize cartesian product
175+ to [N] arguments:
181176
182177 {[
183178 module AList = struct
184179 include List
185- let apply fs xs =
186- cartesian_product fs xs >>| fun (f,x) -> f x
180+
181+ let apply fs xs = cartesian_product fs xs >>| fun (f, x) -> f x
187182 end
188- module Varags = Variadic.Make(AList)
183+
184+ module Varags = Variadic.Make (AList)
189185
190186 let cartesian_product = Varags.apply
191187 ]}
192188
193- For option and error monad, with the following definition of
194- [apply],
195-
196- {[let apply f x = match f,x with
197- | Some f, Some x -> Some (f x)
198- | None -> None]}
189+ For option and error monad, with the following definition of [apply],
199190
200- The produced [Varargs.apply] will be a generalization of
201- [Option.merge], i.e., it will apply function [f] to [N]
202- arguments of different types, if all of them are not zero (i.e.,
203- [None], [Error].
191+ {[
192+ let apply f x =
193+ match (f, x) with Some f, Some x -> Some (f x) | None -> None
194+ ]}
204195
196+ The produced [Varargs.apply] will be a generalization of [Option.merge],
197+ i.e., it will apply function [f] to [N] arguments of different types, if
198+ all of them are not zero (i.e., [None], [Error].
205199
206- @see <http://staff.city.ac.uk/~ross/papers/Applicative.pdf> {v
200+ @see <http://staff.city.ac.uk/~ross/papers/Applicative.pdf>
201+ {v
207202 [1]: Applicative Programming with Effects.
208203 Conor McBride and Ross Paterson.
209204 Journal of Functional Programming 18:1 (2008), pages 1-13.
210- v}
211-
212- *)
205+ v} *)
213206 module Variadic : sig
214207 (* * Variadic argument list. *)
215208 module type S = sig
0 commit comments