Ich bin kürzlich auf Situationen gestoßen, in denen ich eine Prädikatfunktion an eine andere Funktion übergeben muss, und die gesuchte Logik lautet häufig: "Stimmt dieser Wert mit diesem Muster überein?"
Musterabgleich scheint in Deklarationen, doBlöcken und Listenverständnissen bevorzugt zu sein , aber es gibt eine Reihe von Funktionen, die ein Prädikat annehmen a -> Bool, bei denen es sehr praktisch wäre, ein Muster irgendwie zu übergeben. Zum Beispiel takeWhile, until, find, span, usw.
Bisher habe ich \a -> case a of MyCons _ -> True; otherwise -> Falseeine benannte Funktion a la gemacht oder geschrieben, let myPred (MyCons _) = True; myPred _ = False inaber beide scheinen schrecklich hässlich und nicht sehr idiomatisch zu sein. Der "offensichtliche" (und falsche) Weg wäre so etwas wie, \(MyCons _) -> Trueaber das wirft natürlich den Fehler auf, parteiisch zu sein, und selbst dann scheint es einen saubereren Weg zu geben.
Gibt es eine prägnantere / sauberere Möglichkeit, so etwas zu tun? Oder gehe ich die Dinge völlig falsch an?
let myPred...Stil für schlecht halte , aber er fühlt sich viel ausführlicher an, als ich es für eine sehr einfache Idee erwarten würde, was mich zu der Frage führt, ob ich den falschen Baum belle.
maybe :: b -> (a -> b) -> Maybe a -> bund zu definieren und sie bool :: a -> a -> Bool -> adann mit Booleschen produzierenden Funktionen als Argument (e) zu verwenden. zB myCons z f (MyCons x) = f x ; myCons z f _ = zdann anrufen myCons False (const True) aMyConsValue. Dies ist fast das, was Sie geschrieben haben. Es ist nur eine weitere Ebene der "Indirektion" / "Abstraktion" über funktionale Argumente eingebaut.
letKlausel, die Sie nicht mögen , sehr zufrieden - obwohl ich die entsprechendewhereKlausel bevorzuge , damit die Hauptdefinition nicht durcheinander gerät. Wenn Sie dieses Dienstprogramm mehr als einmal benötigen, definieren Sie es natürlich als Funktion der obersten Ebene.