2011-05-11 13 views
8

Załóżmy, że mam wyraz Haskell jak:Haskell wzorzec dopasowania przypadki symetrycznych

foo (Nothing, Just a) = bar a 
foo (Just a, Nothing) = bar a 

istnieje jakikolwiek składni Haskell aby zwinąć te przypadki, więc można dopasować zarówno wzór i określić bar a jako odpowiedź dla obu? A może jest tak zwięzły, jak mogę go zdobyć?

+0

Zobacz również http://stackoverflow.com/questions/5914965/patterns-for-symmetric-functions – kennytm

Odpowiedz

5

To tak zwięźle jak w Haskell. W ML istnieje składnia dla tego, czego chcesz (pisząc wiele wzorców, które wiążą te same zmienne, obok siebie oddzielone przez | z ciałem po ostatnim wzorze), ale w Haskell tam nie ma.

8

Jeśli twój kod jest bardziej skomplikowany niż twój przykład, możesz chcieć zrobić coś takiego, używając instancji Alternative dla Maybe i rozszerzenia PatternGuards (część Haskell2010).

{-# LANGUAGE PatternGuards #-} 
import Control.Applicative 

foo (x, y) | Just a <- y <|> x = bar a 

W przypadku, gdy nie są zaznajomieni z nim, <|> wybiera lewicowo-najbardziej Just jeśli jest jedna i zwraca Nothing inaczej, powodując strażnik wzór na niepowodzenie.

+2

ważnym zastrzeżenie choć - Dopasowuje więcej przypadków niż oryginał kod. foo (Just x, Just y) zostanie dopasowany, więc jeśli nie jest to to, czego chcesz, musisz to zrobić we wcześniejszym przypadku. – mokus

4

Możesz użyć -XViewPatterns, aby dodać dowolne funkcje, aby zwinąć dwie skrzynki w jeden wzór. Twój wzór jest teraz funkcją p że daje coś chcesz, aby dopasować:

foo (p -> (Just a, Nothing)) = bar a 

znacznie prostsze!

Musimy zdefiniować p choć, jak:

p (Nothing, [email protected](Just _)) = (a, Nothing) 
p [email protected](Just _, Nothing) = a 
p a      = a 

czy jakkolwiek chcesz normalizować dane przed ich oglądanie.


Referencje:GHC User's Guide chapter on View Patterns

Powiązane problemy