Pattern Matching a języki funkcyjne

0

Jak można w najprostszy sposób wytłumaczyć czym jest dopasowanie wzorca (ang. pattern matching) w językach funkcyjnych (np. F#)? Wiem, że jest na wikipedii ale może ktoś potrafi to opisać od "innej strony".

0

Dopasowanie wzorca w przypadku języków funkcyjnych jest zgrabnym zapisem if/then/else. Tak w dużym uproszczeniu. Jeżeli jednak przyjrzymy się dokładniej temu mechanizmowi, to zobaczymy, że dopasowanie do wzorca jest też formą polimorfizmu. Jeszcze inaczej można powiedzieć, że dopasowanie jest podobne do porównania, oznaczonego =, znanego z algebry.

7

Najprostszy?

title

0

Chyba najłatwiej będzie jeśli skupisz się na samym określeniu "pattern matching" - niby nic, ale mówi Ci, że chodzi o dopasowanie do wzoru. W polskim języku często pada określenie "na kształt" lub "na wzór" czegoś lub kogoś.

Zatem pattern matching to nic innego jak sprawdzenie czy jedna rzecz- struktura danych, słownik, lista - cokolwiek, jest podobna do drugiej.

Podam Ci przykład z Elixira:

kwadrat = %{boki_rowne: true, katy_proste: true}

# czy kwadrat jest prostokatem 
%{katy_proste: true} = kwadrat # true

Kwadrat spełnia wymagania prostokąta, bo ma wszystkie kąty proste. Zauważ, że nie interesuje nas w tym wypadku czy ma wszystkie boki równe. Sprawdzasz akurat jedną cechę, choć oczywiście w innych przykładach możesz więcej.

Wyobraź sobie, że szukasz dziewczyny, która jest inteligentna, ładna, zabawna i dobrze gotuje - robisz nic innego jak pattern matching, bo ewentualne kandydatki na swoją dziewczynę przykładasz do wzorca, który wcześniej sobie ustaliłeś ;)

0

Ważne jest jeszcze chyba to - że w językach funkcyjnych taki "konstrukt" jak dopasowywanie do wzorca - wpływa również na sterowanie i rozkładania ustrukturyzowanych danych. Przykładowo w F#:

let MinMax a b =
match (a, b) with
| ("min", lo), ("maks", hi) -> (lo, hi)
| ("maks", hi), ("min", lo) -> (lo, hi)
| _ -> failwith "Oczekiwano wartości maksymalnej i minimalnej !"

Czyli tutaj dopasowujesz i badasz dwie pary i łańcuchy znaków z pierwszych
elementów par. Następnie kod zwraca Ci wartości powiązane z tymi elementami

A w Elixirze faktycznie pattern paching jest bardzo zgrabniutko i ciekawie rozwiązany. Jako że to język czysto-funkcyjny (nie jak F#) to zamiast
-> masz po prostu "=" :)

0

Elixir dopiero poznaję, więc może faktycznie zapędziłem się z tym "czystym" ;) Z drugiej strony na pewno jest bardziej funkcyjny niż Scala czy F#, a haskellowe "zboczenia" (monady) to jednak imho przegięcie w drugą stronę... Podoba mi się również że Jose Valim zaadoptował protokoły (mechanizm znany chociażby z Clojure) zamiast wymyślać jakieś odpowiedniki obiektowych interfejsów...

0

Z drugiej strony na pewno jest bardziej funkcyjny niż Scala czy F#, a haskellowe "zboczenia" (monady) to jednak imho przegięcie w drugą stronę

To zgłupiałem, co sprawia że język jest "funkcyjny"? To że wymusza na tobie funkcyjność czy to że można w nim pisać czysto funkcyjnie? A może to że daje narzędzia? Jeżeli drugie albo trzecie to nie wiem w czym jest lepszy elixir od F# :/ (Scala nie jest functional-first).

0
Świetny Kaczor napisał(a):

Z drugiej strony na pewno jest bardziej funkcyjny niż Scala czy F#, a haskellowe "zboczenia" (monady) to jednak imho przegięcie w drugą stronę

To zgłupiałem, co sprawia że język jest "funkcyjny"? To że wymusza na tobie funkcyjność czy to że można w nim pisać czysto funkcyjnie? A może to że daje narzędzia? Jeżeli drugie albo trzecie to nie wiem w czym jest lepszy elixir od F# :/ (Scala nie jest functional-first).

Ja też tego nie rozumiem, bo w sumie w obiektowych językach i tak też trzeba metody pisać funkcyjnie, ale można użyć danych hermetyzowanych albo zewnętrznych.

0

Tyle tylko, że w językach czysto funkcyjnych nie masz efektów ubocznych, ani zmiennych. Wartościowanie jest leniwe i zazwyczaj masz bardzo silny stem typów.Swoją drogą właśnie te „zboczenia” jak monady są jedną z cech języków funkcyjnych.

0

@Koziołek
Jeżeli weźmiemy pod uwagę "przypisanie" w elixirze, to taki pattern matching też jest w środku czymś na wzór if/then/else? W sensie że dopasuj do jednego wzorca i wykonaj dalszą część kodu? Pattern matching jest tam na każdym kroku i sporo by wyszło tych ifów, których procki raczej nie lubią.

2

@krzysiek050: Procki nie lubią skoków warunkowych, ale wystarczy nie przeszkadzać mechanizmom predykcji. To już zadanie kompilatora i potrafimy sobie z tym problemem poradzić.

1 użytkowników online, w tym zalogowanych: 0, gości: 1