2016-05-31 14 views
2

Ich habe eine Liste von Elementen:Haskell Mustererkennung auf Inhalt Liste

data Foo = A Int | B Int | C Int 

myList :: [Foo] 
myList = [A 1, B 2, C 3] 

Ich möchte eine Funktion, die den Wert eines bestimmten Konstruktor wird, falls vorhanden:

-- returns value of the first A constructor, if exists: 
getA :: [Foo] -> Maybe Int 

-- returns value of the first B constructor, if exists: 
getB :: [Foo] -> Maybe Int 

Jede elegante Lösung ? Und was ist mit einer getX Funktion, die in der Lage ist, den Wert eines bestimmten Konstruktors in der Liste zu erhalten?

Antwort

3

wird diese Arbeit

getA theList = listToMaybe [x | A x <- theList] 
getB theList = listToMaybe [x | B x <- theList] 

Sie Data.Maybe importieren müssen.

Verallgemeinern wäre möglich, aber knifflig .... Welchen Typ möchten Sie diese Funktion überhaupt haben? ([a]->somethingToRepresentAConstructor->Int).

+0

Dank bekommen, das ist elegant. Ich vergesse immer das Listenverständnis. – cdupont

+0

In Bezug auf die Generalisierung könnte der somethingToRepresentAConstructor ein String sein? – cdupont

+0

Hmmm, dies zu tun ist sicherlich möglich .... Es auf eine elegante Art und Weise zu tun, das ist eine andere Frage .... Der Brute-Force-Ansatz wäre, es von Hand zu schreiben 'getX" A "= getA; getX "B" = getB'. – jamshidh

1

Und was ist mit einer getX-Funktion, die in der Lage ist, den Wert eines angegebenen Konstruktors in die Liste aufzunehmen?

In Bezug auf die Generalisierung könnte der somethingToRepresentAConstructor ein String sein?

Sie können ein bisschen mehr verallgemeinern und

firstJust :: (a -> Maybe b) -> [a] -> Maybe b 
firstJust f xs = case filter isJust (map f xs) of 
        x : _ -> x 
        [] -> Nothing 

getA = firstJust f 
    where f (A x) = Just x 
     f _ = Nothing 

getB = firstJust f 
    where f (B x) = Just x 
     f _ = Nothing 
+0

Dies ist, was ich derzeit habe, aber ich mochte es nicht, weil es eine Funktion pro Konstruktor gibt. – cdupont

+0

Nicht wirklich. Sie repräsentieren einfach jeden Konstruktortyp - sicher durch eine Funktion anstelle einer Zeichenfolge. Natürlich ist es weniger kompakt (obwohl mit 'LambdaCase' Erweiterung können Sie' firstJust schreiben (\ case {A x -> Nur x; _ -> Nichts}) '). –