2010-07-25 9 views
16

Zmieniam niektóre kody Haskella z używania list do zestawów. Rozumiem wszystko, co jest wymagane, ale nie jestem pewien, jak dopasować wzór do zestawów. Listy mają tę ładną dosłowną składnię, która wydaje się trudna do naśladowania za pomocą konstruktora Set. Na przykład, mogę mieć taki kod:Dopasowywanie wzorca passera na pustym zestawie

foo [] = [] 
foo x = other_thing 

Jak mogę napisać ten kod, aby korzystać z zestawów zamiast list?

Odpowiedz

30

Cóż, nie możesz.

Set jest abstrakcyjne typy danych[0] które celowo zakrywa jej wewnętrzną reprezentację, głównie w celu utrzymania niezmienników struktury danych, które nie mogą być statycznie egzekwowane przez układ typu (konkretnie, średnia biblioteki Data.Set.Set to drzewo wyszukiwania binarnego).

Utrata umiejętności dopasowania wzorca na abstrakcyjnym typie danych jest nieprzyjemnym dodatkowym uszkodzeniem, ale no cóż. Twoje opcje są mniej więcej:

  • Użyj predykatów i zabezpieczeń boolean, np. null, jak w odpowiedzi trinithis. Przetłumacz do listy. Przez większość czasu jest to głupie, ale jeśli chcesz iterować przez set tak czy inaczej, działa to wystarczająco dobrze.
  • Włącz GHC's ViewPatterns extension, która zapewnia cukier syntaktyczny do korzystania z funkcji akcesorów, w których normalnie występuje dopasowanie do wzorca.
  • Unikaj dokonywania takich kontroli w pierwszej kolejności - jeśli masz numer Set, traktuj go jak zestaw i pracuj z nim jako całością podczas mapowania, filtrowania itp. Nie zawsze jest to możliwe, ale może prowadzić do czystszego kodu z mniej wyraźnych warunkowych/iteracji.

Zobacz wzory pozwolił napisać coś, co wygląda tak:

foo (setView -> EmptySet) = [] 
foo (setView -> NonEmpty set) = other_thing 

... gdzie setView jest funkcją piszesz. Nie bardzo dużo zysku tutaj, ale może być miły dla bardziej złożonych pseudo-wzorców

Dla uniknięcia wyraźnych kontrole, oprócz dobrze znanych operacji zestaw takich jak union i intersection, rozważ użycie filter, partition, map, i fold funkcje w Data.Set.

[0]: Zobacz this paper (Uwaga: PDF) Definicja pojęcia jak używam go.

+0

+1 dla referencji ViewPatterns! – ShiDoiSi

29
import qualified Data.Set as Set 

foo set 
    | Set.null set = bar 
    | otherwise = baz 
+1

+1 dla prostej odpowiedzi –

+7

@simonjpascoe: Czekaj, możemy dać * proste * odpowiedzi? I tutaj przez cały ten czas myślałem, że istnieje minimum trzech akapitów ... –

Powiązane problemy