如何在OCaml中编写一个函数,其中一个或多个参数是可选的?
let foo x y z = if(x+y > z) then true else false;;
如果foo没有收到z
参数,则会将0
用作z
。
foo 3 3 2 -> true
foo 3 3 10 -> false
foo 2 1 -> true
是否有任何OCaml功能可以实现这一目标?
答案 0 :(得分: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
一般来说,我会说OCaml中的可选(和命名)参数不能解决与其他语言相同的问题。
我个人从不用可选参数定义函数;所以,可能有更好的方法来实现你所要求的。
答案 1 :(得分:11)
OCaml没有像您在Java或C#中找到的可选参数。由于可以部分应用函数,因此可选参数可能使您很难判断何时传递参数并希望对函数进行求值。但是,OCaml确实有labeled arguments with default values,可以用于同样的效果。
标记参数的常见警告适用。请注意,标记的参数不能出现在参数列表的末尾,因为只要函数具有所需的一切,就会对其进行评估:
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>
参数列表的其他部分很好:
# 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
以与上述相同的方式,一旦您超越“#”,您将无法提供可选参数。它在参数列表中:
# foo 1;;
- : int -> bool = <fun>