Reputation: 8552
I am trying to implement a simple range function in OCaml and I was wondering how can i do that for different arity calls.
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
This obviously does not work the last definition wins. Is there a way to define multiple arity functions?
Upvotes: 4
Views: 258
Reputation: 18892
Overloading of function does not exist in OCaml in general. For your specific use case, it is possible to use optional arguments:
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
where ?(start=0)
means that the named argument start
is optional and its default value is 0
.
Note that I made stop
a positional argument since the compiler needs a least one positional argument to know when to consume optional arguments.
Another possibility would have been to add an unit argument as a last argument:
let range ?(start=0) ?(step=1) ~stop () = range_aux ~start ~step ~stop
let a = range ~stop:2 ()
p.s. your range_aux
will descend into an infinite recursion when start > stop
or (stop - start) mod step ≠ 0
.
Upvotes: 6