OCaml/Nazwane i opcjonalne argumenty funkcji

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ć.


< powrót do spisu treści