Важна позиция необязательных аргументов (в объявлении или типе функции): они применяются неявно только при применении следующего необязательного аргумента.
Если вы хотите частичное применение одного из нихпараметр p
, чтобы не применять необязательный параметр ?o
, поставить ?o
после p
в объявлении функции.
Контраст
# let f ?o p ~z = ();;
val f : ?o:'a -> 'b -> z:'c -> unit = <fun>
# f 1;;
- : z:'_a -> unit = <fun> (* ?o applied *)
с:
# 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 *)
Если вы не хотите изменять порядок определения или хотите частично применить все необязательные параметры, вам необходимо явно захватить необязательные параметры, которые будут неявно переданы:
# (fun ?o () -> f ?o 1 ~z:2);;
- : ?o:'a -> unit -> unit = <fun>
В случае, если вы не были знакомы с этим, синтаксис ?o
на сайте вызова очень удобен для этого: он принимает 'a option
и правильно делает прозрачную передачу необязательного аргумента, независимо от того, применен он или нет, к вызываемому объекту..
Я добавил последний параметр ()
, чтобы сохранить свойство, что после необязательных есть хотя бы один необязательный аргумент.Можно этого не делать, но это сложно и не рекомендуется.