/ / Informationen aus dem Haskell-Objekt extrahieren - haskell

Informationen aus dem Haskell-Objekt extrahieren - haskell

Ich bin neu bei Haskell und ich bin verwirrt darüber, wie es gehtWerte außerhalb der Funktionsergebnisse. In meinem speziellen Fall versuche ich, Haskell-Dateien zu analysieren und zu sehen, welche AST-Knoten in welchen Zeilen angezeigt werden. Dies ist der Code, den ich bisher habe:

import Language.Haskell.Parser
import Language.Haskell.Syntax

getTree :: String -> IO (ParseResult HsModule)
getTree path = do
file <- readFile path
let tree = parseModuleWithMode (ParseMode path) file
return tree

main :: IO ()
main = do
tree <- getTree "ex.hs"
-- <do something with the tree other than print it>
print tree

Also auf der Zeile, wo ich den Kommentar habe, habe ich einen Syntaxbaum als tree. Es scheint Typ zu haben ParseResult HsModule. Was ich will ist nur HsModule. Ich denke, wonach ich suche ist eine Funktion wie folgt:

extract :: ParseResult a -> a

Oder noch besser, eine allgemeine Haskell-Funktion

extract :: AnyType a -> a

Vielleicht fehlt mir hier ein wichtiges Konzept von Haskell?

p.s. Ich verstehe, dass es falsch ist, wenn man diese Dinge als "Objekte" betrachtet und versucht, von ihnen "Felder" zu erreichen, aber ich würde gerne erklären, wie man mit dieser Art von Dingen im Allgemeinen umgeht.

Antworten:

3 für die Antwort № 1

Die Definition von ParseResult ist:

data ParseResult a = ParseOk a | ParseFailed SrcLoc String

(aus dem Quellcode erhalten)

Es gibt also zwei Möglichkeiten: Entweder ist das Parsen erfolgreich und es wird a zurückgegeben ParseOk Englisch: www.weisang.info/index.php?id=143&t...h=ddb8d5dcf9 Während des Parsens ist eine falsche Instanz oder etwas falsch gelaufen ParseFailed Konstrukteur.

So können Sie eine Funktion definieren:

getData :: ParseResult a -> a
getData (ParseOk x) = x
getData (ParseFailed _ s) = error s

Es ist besser, dann auch einen Fehler zu werfen, da es immer möglich ist, dass Ihr Compiler / Interpreter / Analysator / ... ein Haskell-Programm analysiert, das Syntaxfehler enthält.


7 für die Antwort № 2

Auf der Suche nach einer allgemeinen Funktion des Typs

extract :: AnyType a -> a

zeigt tatsächlich ein großes Missverständnis über Haskell. Betrachten Sie die vielen Dinge AnyType könnte sein, und wie Sie genau ein Objekt daraus extrahieren könnten. Wie wäre es mit Maybe Int? Sie können leicht genug konvertieren Just 5 zu 5, aber für welche Nummer sollten Sie zurückkehren? Nothing?

Oder was wenn AnyType ist [], damit du es hast [String]? Was sollte das Ergebnis sein?

extract ["help", "i"m", "trapped"]

Oder von

extract []

?

ParseResult hat ein ähnliches "Problem", indem es verwendet ParseOk um Ergebnisse zu enthalten, die anzeigen, dass alles in Ordnung war, und ParseFailed um einen Fehler anzuzeigen. Ihre unvollständige Musterübereinstimmung erhält das Ergebnis, wenn die Syntaxanalyse erfolgreich war, stürzt jedoch Ihr Programm ab, wenn die Analyse tatsächlich fehlgeschlagen ist. Durch die Nutzung ParseResult, Haskell ermutigt dich zu überlegen, was du tun sollst, wenn der Code, den du analysierst, nicht korrekt analysiert wurde, anstatt einfach nur zu glauben, dass es gut ausgehen wird.


1 für die Antwort № 3

Ich habe gerade herausgefunden, wie das geht. Es scheint, dass wenn ich versuchte zu definieren

extract :: ParseResult a -> a
extract (ParseResult a) = a

Ich musste wirklich benutzen

extract :: ParseResult a -> a
extract (ParseOk a) = a

stattdessen. Ich bin mir nicht 100% sicher, warum das so ist.