OCaml/Nazwane i opcjonalne argumenty funkcji
< OCaml
Jak każdy nowoczesny język Caml udostępnia programiście możliwość nazywania argumentów funkcji oraz tworzenia opcjonalnych argumentów. Również moduły biblioteki o nazwie zakończonej na "Label" udostępniają funkcje z nazwanymi argumentami. Ułatwia to zarządzanie i dokumentowanie kodu.
# let example ~x ~y =
printf "%d %.2f\n" x y;;
val example : x:int -> y:float -> unit = <fun>
# example ~x:4 ~y:10.0;;
4 10.00
- : unit = ()
Ze względu na to, że nie podawanie części argumentów (tzw. częściowa aplikacja) ma w języku specjalne znaczenie, programista musi pokazać kiedy ma zostać użyty opcjonalny argument. Dlatego za opcjonalnymi argumentami musi występować przynajmniej jeden nieopcjonalny i nienazwany. Najczęściej stosuje się typ unit.
# let incr ?(by=1) x = x + by;;
val incr : ?by:int -> int -> int = <fun>
# incr 5;;
- : int = 6
# incr ~by:10 3;;
- : int = 13
(* Są zaimplementowane jako typ wariacyjny.
* Powyższe można w analogiczny sposób zapisać tak: *)
# let incr ?by x =
match by with
| None -> x + 1
| Some step -> x + step;
;;
val incr : ?by:int -> int -> int = <fun>
(* Ich typ to: *)
type 'a option = None | Some of 'a
(* Jeszcze jeden przykład: *)
# let test ?(x = 0) ?(y = 0) () = (x, y);;
val test : ?x:int -> ?y:int -> unit -> int * int = <fun>
# test ();;
- : int * int = (0, 0)
# test ~x:4 ();;
- : int * int = (4, 0)
# test ~x:4 ~y:5 ();;
- : int * int = (4, 5)
# test ~x:4 ~y:5 ;;
- : unit -> int * int = <fun>
Dzięki temu, że funkcja pobiera argument unit
kompilator języka
wie, kiedy chcemy ją ostatecznie zastosować.