OCaml可选参数

use*_*997 4 ocaml functional-programming

如何在OCaml中编写一个函数,其中一个或多个参数是可选的?

let foo x y z = if(x+y > z) then true else false;;
Run Code Online (Sandbox Code Playgroud)

如果foo没有收到z0用作的参数z.

foo 3 3 2 -> true
foo 3 3 10 -> false
foo 2 1 -> true
Run Code Online (Sandbox Code Playgroud)

是否有任何OCaml功能来实现这一目标?

Jef*_*eld 15

OCaml有可选的参数,但它比你想象的要复杂得多,因为OCaml函数从根本上只有一个参数.在您的情况下,foo是一个需要int并返回一个函数的函数.

如果你不使用尾随参数,通常这意味着你对将要返回的函数感兴趣; 这有时被称为部分应用.

结果是跟踪可选参数(正如您所要求的)不起作用.

可选参数始终与名称相关联,该名称用于指示是否提供参数.

如果您创建z函数的第一个参数而不是最后一个参数,则可以得到如下内容:

# 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
Run Code Online (Sandbox Code Playgroud)

一般来说,我会说OCaml中的可选(和命名)参数不能解决与其他语言相同的问题.

我个人从不用可选参数定义函数; 所以,可能有更好的方法来实现你所要求的.


Gor*_*son 11

OCaml没有像你在Java或C#中找到的可选参数.由于函数可以部分应用,因此可选参数可能很难判断您何时完成传递参数并希望对函数进行求值.但是,OCaml确实使用默认值标记了参数,这可以用于相同的效果.

标记参数的常见警告适用.请注意,标记的参数不能出现在参数列表的末尾,因为只要函数具有所需的一切,就会对其进行求值:

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>
Run Code Online (Sandbox Code Playgroud)

参数列表的其他部分很好:

# 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
Run Code Online (Sandbox Code Playgroud)

以与上面相同的方式,一旦你在参数列表中移过它,你就失去了提供可选参数的能力:

# foo 1;;
- : int -> bool = <fun>
Run Code Online (Sandbox Code Playgroud)