Eine unvollständige Musterübereinstimmung vermeiden

8

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?

    
Clinton 06.07.2017, 09:04
quelle

3 Antworten

1

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).

%Vor%

Bei Listen sollte dies nur Platz proportional zur Anzahl der führenden A s annehmen, was minimal ist, glaube ich.

    
Clinton 06.07.2017, 13:54
quelle
2

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.

    
MathematicalOrchid 06.07.2017 10:13
quelle
2

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:

%Vor%

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:

%Vor%

Ich leihe (a, b) 's Monoid instance , die parallel an a und b Monoid Instanzen delegiert.

%Vor%

Alternativ mit foldr :

%Vor%

Schau, ma, keine Teilfunktionen!

    
Benjamin Hodgson 06.07.2017 10:27
quelle