OCaml Optional Argument

吃可爱长大的小学妹 提交于 2019-12-04 10:47:38

OCaml doesn't have optional arguments like you'd find in Java or C#. Since functions can be partially applied, optional arguments can make it hard to tell when you're done passing arguments and would like the function to be evaluated. However, OCaml does have labeled arguments with default values, which can be used to the same effect.

The usual caveats of labeled arguments apply. Note that labeled arguments can't appear at the end of the argument list since the function is evaluated as soon as it has everything it needs:

let foo x y ?z_name:(z=0) = (x + y) > z;;
Characters 12-39:
  let foo x y ?z_name:(z=0) = (x + y) > z;;
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Warning 16: this optional argument cannot be erased.
val foo : int -> int -> ?z_name:int -> bool = <fun>

Other parts of the argument list are fine:

# let foo ?z:(z=0) x y = (x + y) > z;;
val foo : ?z:int -> int -> int -> bool = <fun>
# foo 1 1;;
- : bool = true
# foo (-1) (-1);;
- : bool = false
# foo ~z:(-42) (-1) (-1);;
- : bool = true

In the same fashion as above, you lose the ability to supply the optional argument once you 'move past' it in the argument list:

# foo 1;;
- : int -> bool = <fun>

OCaml has optional arguments, but it's quite a bit trickier than you would expect because OCaml functions fundamentally have exactly one argument. In your case, foo is a function that expects an int and returns a function.

If you leave off trailing arguments, normally this means that you're interested in the function that will be returned; this is sometimes called partial application.

The result is that trailing optional arguments (as you are asking for) do not work.

Optional arguments are always associated with a name, which is used to tell whether the argument is being supplied or not.

If you make z the first argument of your function rather than the last, you can get something like the following:

# let foo ?(z = 0) x y = x + y > z;;
val foo : ?z:int -> int -> int -> bool = <fun>
# foo 3 3 ~z: 2;;
- : bool = true
# foo 3 3 ~z: 10;;
- : bool = false
# foo 2 1;;
- : bool = true

In general I'd say that optional (and named) arguments in OCaml don't solve the same problems as in some other languages.

I personally never define functions with optional arguments; so, there may be better ways to achieve what you're asking for.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!