在OCaml中定义多个arity函数的正确方法是什么?

Ist*_*van 4 ocaml

我试图在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函数?

oct*_*ron 6

一般来说,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.