OCaml/Listy
Listy zbudowane są z wielu elementów tego samego typu. Pustą listę oznacza się symbolem [], natomiast operator :: doczepia na początku listy nowy element. Można je tworzyć na dwa sposoby; rekurencyjnie -- doczepiając do pustej listy kolejne elementy, lub w równoważny sposób -- podając w kwadratowym nawiasie elementy oddzielone średnikami. Spójrzmy na poniższy przykład:
# [1;2;3;4;5];;
- : int list = [1; 2; 3; 4; 5]
# 1 :: 2 :: 4 :: 5 :: [];;
- : int list = [1; 2; 4; 5]
# ['a'; 'b'; 'c'; 'd'];;
- : char list = ['a'; 'b'; 'c'; 'd']
# [];;
- : 'a list = []
Typem ogólnym listy jest 'a list
, gdzie 'a jest
"typem polimorficznym", który oznacza "dowolny typ". Szczególnymi przypadkami
list może być lista intów: int list
lub znaków: char
list
. Do łączenia dwóch list w jedną używany jest operator '@'.
Jeśli OCaml nie będzie w stanie określić typu któregoś z argumentów funkcji, stworzy funkcję polimorficzną, która może przyjąć argument o dowolnym typie. Wiele z funkcji z biblioteki standardowej jest właśnie tak zbudowana. Dla przykładu rozważmy funkcję List.map:
# List.map;;
- : ('a -> 'b) -> 'a list -> 'b list = <fun>
# List.map (fun a -> a + 5) [1; 2; 3];;
- : int list = [6; 7; 8]
Funkcja ta przyjmuje dwa argumenty: Funkcję ('a -> 'b)
przyjmującą jeden
argument dowolnego typu, i zwracającą argument innego typu (lub tego samego,
ale niekoniecznie) oraz 'a list
, czyli listę tego samego typu, który
przyjmuje funkcja i zwraca listę elementów ('b list)
zwracanych przez
funkcję. Trochę to było skomplikowane ale wybrnęliśmy.
W tym przykładzie również możemy zauważyć zastosowanie funkcji anonimowej:
(fun a-> a+5)
, która została stworzona specjalnie na potrzeby wywołania List.map --
nie posiada własnej nazwy i nie może być później użyta ponownie.