Suppose a function bind
has a labelled argument, optional arguments and unlabelled arguments, and you want to define a method m
that applies the unlabelled arguments of bind
and returns the partially applied function, so that the user of m
can apply the labelled or optional arguments of bind
. How do you do this? Simply writing method m = bind a b [...] z
causes the compiler to think that the optional arguments are omitted.
You can assign an optional argument using the assignment operator in a function definition or using the Python **kwargs statement. There are two types of arguments a Python function can accept: positional and optional. Optional arguments are values that do not need to be specified for a function to be called.
So, it is optional during a call. If a value is provided, it will overwrite the default value. Any number of arguments in a function can have a default value. But once we have a default argument, all the arguments to its right must also have default values.
Similarly, OCaml functions do not have to have names; they may be anonymous. For example, here is an anonymous function that increments its input: fun x -> x + 1 . Here, fun is a keyword indicating an anonymous function, x is the argument, and -> separates the argument from the body.
The position of the optional arguments (in the function declaration or function type) is important: they are only applied implicitly when the next non-optional argument is applied.
If you want the partial application of one parameter p
to not apply an optional parameter ?o
, put ?o
after p
in the function declaration.
Contrast
# let f ?o p ~z = ();;
val f : ?o:'a -> 'b -> z:'c -> unit = <fun>
# f 1;;
- : z:'_a -> unit = <fun> (* ?o applied *)
with:
# let f p ?o ~z = ();;
val f : 'a -> ?o:'b -> z:'c -> unit = <fun>
# f 1;;
- : ?o:'_a -> z:'_b -> unit = <fun> (* ?o not applied *)
If you don't want to change the definition order, or want to partially apply all non-optional parameters, you need to explicitly capture the optional parameters that would be implicitly passed:
# (fun ?o () -> f ?o 1 ~z:2);;
- : ?o:'a -> unit -> unit = <fun>
In case you weren't familiar with it, the ?o
syntax at call site is
very handy for this: it takes an 'a option
and does the right thing to
transparently pass an optional argument, whether applied or not, to the
callee.
I have added a last ()
parameter to preserve the property that there
is at least one non-optional argument after the optional ones. It is possible to not do this, but it gets tricky and is not advised.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With