Ocaml函数的可选参数和命名参数

2017-12-10  本文已影响0人  只今参上

Ocaml新人,在这里记录一下自己的学习心得,欢迎各路大佬批评指正~

?foo 和 ~foo 在OCaml中分别表示函数的可选和命名参数。这个特性在C衍生的语言中未必有对于的概念,但是Perl,Python和Smalltalk都允许函数忽略某些参数,或者以其他顺序传入参数。

例1:

    #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

例2:

    #let fcc x u ?z:(z=0) = (x+y)>z;;

Characters 16-19:

Warnig 16:this optional argument cannot be erased.

cal fcc : int -> int -> ?z:int -> bool = <fun>

    #fcc 1 1;;

    - : ?z:int -> bool = <fun>

    fcc 1 1 ~z:(3);;

    - : bool = false

如例1例2,在定义函数的时候,可以用 ?(z=0) 或者 ?z:(z=0) 的形式为参数 z 设定默认值0。用法与c++中函数的默认参数类似,但是规则却是有很大差异:在Ocaml中设置可选参数时,它们不可出现在参数列表的末尾,这可能是函数式编程的特性吧,在下目前还没有理解透,不过在这贴一段国外大神的见解,"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"。

在例1语句 foo 1 1;; 中,z的值为默认值0,x的值为1,y的值为1,由2>0可知,函数的结果为true。

但是,如果想要在调用函数的时候,手动传入z的值,则需要以 ~z:(42) 的形式“显式”地传入参数 z 的值42,如例1语句 # foo ~z:(-42) (-1) (-1);; ,但是,像 foo 42 1 1 这种写法会出现形如 “Error: The function applied to this argument has type ?z:int -> bool” 的报错。

在例2中,经过实践发现,如果可选参数出现在参数列表末尾,那么我们将无法使用其内设置的默认值,必须手动传入命名参数,函数才会进行运算并返回值。

上一篇 下一篇

猜你喜欢

热点阅读