我试图在OCaml中实现一个简单的范围函数,我想知道如何为不同的arity调用做到这一点.
let range_aux ~start ~stop ~step =
let rec aux start stop step acc =
match (start, stop, step, acc) with
| (start,stop,step,acc) when start = stop -> List.rev acc
| (start,stop,step,acc) -> aux (start + step) stop step (start :: acc) in
aux start stop step []
let range ~start ~stop ~step = range_aux ~start ~stop ~step
let range ~stop ~step = range_aux ~start:0 ~stop ~step
let range ~stop = range_aux ~start:0 ~stop ~step:1
Run Code Online (Sandbox Code Playgroud)
这显然不适用于最后一个定义胜利.有没有办法定义多个arity函数?
一般来说,OCaml中不存在功能的重载.对于您的特定用例,可以使用可选参数:
let range ?(start=0) ?(step=1) stop = range_aux ~start ~step ~stop
let a = range 2
let b = range ~start:1 2
let c = range ~start:1 ~step:2 5
Run Code Online (Sandbox Code Playgroud)
where ?(start=0)表示命名参数start是可选的,其默认值是0.
请注意,我创建stop了一个位置参数,因为编译器需要至少一个位置参数来知道何时使用可选参数.另一种可能性是添加一个单位参数作为最后一个参数:
let range ?(start=0) ?(step=1) ~stop () = range_aux ~start ~step ~stop
let a = range ~stop:2 ()
Run Code Online (Sandbox Code Playgroud)
ps range_aux当你start > stop或者你的意志下降到无限递归(stop - start) mod step ? 0.