Frage

Ich finde, dass ich viel Code schreibe wie

putStr "foo (bar 1) (bar 2) ="
print $ foo (bar 1) (bar 2)

Das Problem ist, dass die gedruckte Nachricht möglicherweise nicht mehr mit dem tatsächlich ausgeführten Code synchronisiert ist.Die naheliegende Lösung besteht darin, diesen Code automatisch zu generieren.

Eine Möglichkeit, dies zu tun, besteht darin, den gesamten Text in eine Datei zu schreiben und ein kleines Programm zu schreiben, das die Datei liest und daraus Haskell-Quellcode generiert.Eine andere Alternative ist die Verwendung von Template Haskell .

Weiß jemand, wie ich vorgehen würde, um eine Funktion zu schreiben, die eine String und generiert den obigen Code daraus?Ich vermute, es sollte ziemlich einfach sein, aber DAS ist nicht gut dokumentiert.

War es hilfreich?

Lösung

Sie können Haskell-Code mit dem haskell-src-meta Paket analysieren.Hier ist ein kurzes Beispiel, wie Sie dies mit der Vorlage Haskell kombinieren könnten. generasacodicetagpre.

und Sie würden es so verwenden generasacodicetagpre.

Andere Tipps

Template Haskell bietet kein einfaches Mittel zur Analyse von willkürlichen Saiten, sodass die einfachste Lösung wahrscheinlich den C-Vorverarbeitungsmesser verwenden soll.Der eingebaute in GHC unterstützt jedoch keine Feststellung, sodass wir zusätzliche Optionen bestehen, um den "echten" stattdessen verwenden. generasacodicetagpre.

Sie können es dann so verwenden: generasacodicetagpre.

Es gibt ein Beispiel für den generierten Haskell-Code mit GHC API hier .

autsch. Ich bin dachte, das wäre einfach, aber soweit ich sagen kann, ist es eigentlich unmöglich .

Ich hatte erwartet, dass es eine Funktion gab, die eine Zeichenfolge in einen Ausdruck schaltet, aber anscheinend existiert keine solche Funktion. Es ist nicht einmal eine Funktion, um mehr Quellcode von der Festplatte zu laden. Es scheint also, dass diese Aufgabe eigentlich unmöglich ist! Ich bin ziemlich überrascht davon.

Das nächste, was ich tun könnte, ist, den Ausdruck zu zitieren, den ich ausführen möchte, und baue dann einen Spleiß auf, der hübsch druckt den zitierten Ausdruck, bevor er ihn ausgeführt hat. Das bringt mich jedoch auf die Barmherzigkeit von GHCs Ausdruck Hübsches Drucker. Das Etikett kommt nicht extra genau , während ich es tippte. (Insbesondere scheint es, Betreiber mit vollständig qualifizierten Namen zu ersetzen, was nur schmerzhaft ist.)

Sie hätten gedacht, dass ein Merkmal so ziemlich trivial ist, um zu implementieren. Die Tatsache, dass sie nicht implementiert ist, kann daher nur einem von zwei Dingen zugeschrieben werden:

    .
  1. Niemand braucht diese Funktion tatsächlich. (Nun, außer mir, offensichtlich.)

  2. Es ist nicht so trivial, wie es aussieht. (Z. B. herauszufinden, welchen Kontext den Expression in analysieren, irgendwie fummeln?)

Sie können auch die Speicherabbilddatei paket, das genau für diesen Anwendungsfall geschrieben wurde:

{-# language QuasiQuotes #-}
import Debug.Dump

main = putStrLn [d| foo (bar 1) (bar 2) |]

foo = (+)
bar = (+1)

Welcher druckt: (foo (bar 1) (bar 2)) = 5

Es behandelt auch mehr als einen Ausdruck, der durch Kommas getrennt ist:

putStrLn [d| foo (bar 1) (bar 2), map bar [1, 2] |]

Welcher druckt: (foo (bar 1) (bar 2)) = 5 (map bar [1, 2]) = [2,3]

Bonus:Wenn Sie nix-shell installiert haben (Teil des nix-Paketmanager) mit diesem "Einzeiler" können Sie es sogar schnell ausprobieren:

$ nix-shell -p "nix-shell -p "haskellPackages.ghcWithPackages (p: [p.dump])" --run "echo '{-# language QuasiQuotes #-}; import Debug.Dump; foo = (+); bar = (+1); main = putStrLn [d| foo (bar 1) (bar 2), map bar [1, 2] |]' | runhaskell"

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top