Betrachten Sie den folgenden Code:
%Vor% Die Idee dahinter ist, dass ich eine Liste von A
s oder B
s zusammen gemischt habe. Ich kann A -> B
konvertieren, aber nicht umgekehrt. Basierend auf dieser Liste möchte ich entweder eine Liste von A
s oder eine Liste von B
s erstellen, die erste, wenn alle meine ursprünglichen Listenelemente A
s sind, die letztere, wenn mindestens eine B
ist .
Der obige Code kompiliert (und ich schätze, wird funktionieren), aber die unvollständige Musterübereinstimmung in map (\(TA x) -> x) l
macht mich nur ein wenig unbehaglich. Ist solch eine unvollständige Übereinstimmung nur eine Notwendigkeit dessen, was ich hier mache? Außerdem, erfinde ich das Rad neu, gibt es etwas, das verallgemeinert, was ich hier mache?
Nach ein wenig Hilfe von den anderen Antworten werde ich meine eigene Frage zum Nutzen zukünftiger Zuschauer beantworten. Ich glaube, die stärkste Funktion für g
ist wie folgt (und ich habe bemerkt, dass ich auf Traversable
statt auf Listen verallgemeinert habe).
Bei Listen sollte dies nur Platz proportional zur Anzahl der führenden A
s annehmen, was minimal ist, glaube ich.
Der einzige Weg, an den ich denken kann, ist etwas wie
%Vor% Wenn tryA
nichts zurückgibt, dann mache map f' l
wie zuvor.
Auf diese Weise machst du die all isA l
und die map
in einem einzigen Durchgang und es vermeidet ein unvollständiges Muster.
Ich würde es so strukturieren: bilde zwei Listen - eine voll von A
s und eine voll von B
s - mit dem Effekt, dass die Liste von A
s aufgebaut wird könnte scheitern. Man kann ein Monoid
erstellen, das diese Logik implementiert und foldMap
hinein.
Da es nicht möglich ist, eine Liste von A
s zu erstellen, müssen wir diese Monoid
vor Maybe
erstellen. Das gewünschte Verhalten kommt von Maybe
s Applicative
instance: Wenn eines der Argumente von mappend
Nothing
ist, dann scheitert das Ganze, andernfalls wollen wir mappend
verwenden, um die beiden Ergebnisse zu kombinieren. Dies ist ein allgemeines Rezept für die Kombination von Applicative
und Monoid
. Konkret:
Ich weiß nicht, ob diese newtype
irgendwo in base
ist. Es scheint wie die Art von Dingen, die da wären, aber ich konnte es nicht finden.
Ohne weitere Umschweife, hier ist die Monoid
wir werden foldMap
ping in:
Ich leihe (a, b)
's Monoid
instance , die parallel an a
und b
Monoid
Instanzen delegiert.
Alternativ mit foldr
:
Schau, ma, keine Teilfunktionen!
Tags und Links haskell list pattern-matching refactoring partial