So mappen Sie (Entweder String (a - b)) zu (Entweder String [(a - b)])

7

Ich versuche, eine Lösung für eine eigene Übung mit folgenden Anforderungen zu finden:

  • Wir müssen ein Objekt gegen eine bestimmte Sequenz verschieben.
  • Eine Sequenz besteht aus Aktionen.

Hier sind die möglichen Aktionen: F, L, R

  • F: vorwärts bewegen
  • L: um 90 ° nach links drehen
  • R: um 90 ° nach rechts drehen

Eine Sequenz wird dann durch eine Zeichenfolge wie folgt dargestellt:

"FFLRLFF"

Ich möchte die obige Sequenz analysieren (und Fehler behandeln) und dann jede Aktion an eine Funktion wie folgt binden:

%Vor%

Nun, was ich will, ist etwas mit folgender Unterschrift:

%Vor%

Ich möchte eine vollständige Sequenz analysieren, indem ich oft parseAction function benutze, und scheitere, wenn diese Links zurückkommt. Ich bin fest, wie kann ich diese Funktion implementieren.

Haben Sie irgendwelche Ideen?

    
Maxime B. 11.09.2015, 19:40
quelle

3 Antworten

11

Das sieht wie

aus %Vor%

wo

%Vor%

Eine Implementierung ist einfach:

%Vor%

Beachten Sie, dass Ihr parseAction nicht unbedingt den Typ (a -> a) verwenden möchte. Dieser muss für any vom Typ a funktionieren, der von der Person ausgewählt wird, die die Funktion aufruft . Sie möchten stattdessen, dass der Typ (Location -> Location) verwendet wird, wobei Position der von Ihnen verwendete Typ ist, um den Speicherort des verschobenen Objekts zu repräsentieren.

Äquivalent zu mapM können Sie (wie von duplode vorgeschlagen) stattdessen traverse verwenden, was etwas allgemeiner ist. In neueren Versionen von GHC ist Traverse in Prelude; in älteren Versionen müssen Sie es möglicherweise aus Data.Traversable importieren, um es zu verwenden.

    
amalloy 11.09.2015, 19:57
quelle
7

Hinweis: Zur besseren Übersicht verwende ich Thing -> Thing anstatt a -> a .

Sie benötigen traverse :

%Vor%

In Ihrem Fall ist t [] und so ist t Char String . traverse parseAction wird über die String laufen, eine Aktion für jede Char generieren und die Ergebnisse sammeln. traverse verwendet die Applicative -Instanz von Either , um Left s und Right s zu verarbeiten, und stoppt bei der ersten Left .

P.S .: mapM in amalloy's Antwort entspricht in diesem Fall traverse . Der einzige Unterschied zwischen ihnen ist, dass traverse allgemeiner ist, da nur Applicative (anstatt Monad ) vom Funktor benötigt wird, den Sie beim Traversieren verwenden.

    
duplode 11.09.2015 20:05
quelle
2

Wenn Sie parseAction der Quellzeichenfolge zuordnen, erhalten Sie einen Teil davon. In GHCi:

%Vor%

Jetzt können Sie dies in einen einzigen Wert falten

%Vor%

Dies hat jedoch einen ärgerlichen "Fehler" -Fall. Um das los zu werden:

%Vor%     
Paul Johnson 11.09.2015 20:00
quelle

Tags und Links