Frage

Ich arbeite derzeit mit Haskell an Project und habe mir einige Ärger gehabt. Ich soll in einer Liste in einer "Dictionary.txt" -Datei in eine Liste lesen und einfügen, aber ich kann dies nicht tun. Ich habe diesen Code:

main = do
    let list = []
    loadNums "dictionary.txt" list

loadNums location list = do
    inh <- openFile location ReadMode
    mainloop inh list
    hClose inh

mainloop inh list = do 
    ineof <- hIsEOF inh
    if ineof
        then return ()
        else do 
            inpStr <- hGetLine inh
            inpStr:list
            mainloop inh list

Es soll jede Zeile erhalten (ich weiß, dass es jede Zeile erhält, da das Ersetzen der "INPSTR: Liste" durch ein "putstrln Inpstr" korrekt funktioniert, alle Zeilen anzeigen) und sie in eine Liste einfügen, aber ich erhalte den folgenden Fehler :

Couldn't match expected type `IO' against inferred type `[]'

Wahrscheinlich, weil die HGetline keine Zeichenfolge, sondern eine IO -Zeichenfolge ist, die ich nicht mit der Handlung habe, um eine ordnungsgemäße Zeichenfolge zu erhalten, die ich in meine Liste einfügen kann. Ich habe keine Ahnung, wie dies gelöst werden könnte oder wie genau das Problem ist, aber wenn jemand eine Vorstellung davon hat, wie man jede Zeile in einer Datei in eine Liste richtig einbringt, würde ich es schätzen.

Danke im Voraus!

War es hilfreich?

Lösung

In der Zeile, in der der Fehler auftritt, erwartet Haskell "io a", aber Sie geben ihm eine []. Die Dinge zu vereinfachen, auf einem Do -Block auf dem IO -Monad, jede Zeile ist entweder:

  • Etwas, das einen Wert des "io a" -Typs zurückgibt; Der Wert des "A" -Typs darin wird verworfen (so dass das "a" oft "()")
  • A <- Ausdruck, der dasselbe tut, aber anstatt den Wert des "a" -Typs zu verwerfen, gibt ihm den Namen links vom <-
  • A let, was nichts anderes tut, als einem Wert einen Namen zu geben

In diesem Block gibt die "HGetline -Inh" eine "IO -String" zurück, und die darin enthaltene Zeichenfolge wird extrahiert und den Namen inpstr gegeben. Die nächste Zeile, da es weder ein Let noch ein <-einen Typ "io a" haben sollte, was dies nicht der Fall ist (wodurch der Compiler-Fehler verursacht wird). Was Sie stattdessen tun können, da Sie bereits die Zeichenfolge haben, ist ein Let:

let list' = inpStr:list

Dadurch wird eine neue Liste erstellt, die aus der Zeichenfolge besteht, gefolgt von der ursprünglichen Liste, und gibt ihr den Namen "Liste" ".

Ändern Sie die folgende Zeile, um "Liste" anstelle von "Liste" zu verwenden (so die neue Liste übergeben). Diese Zeile ruft (rekursiv) Mainloop auf, die eine weitere Zeile lesen, sich selbst nennen und so weiter. Nach dem Lesen der gesamten Datei wird etwas mit dem Typ "io ()" zurückgegeben. Dieses "io ()" wird in den Block bei Loadnums zurückgegeben. Herzlichen Glückwunsch, Sie haben gerade eine Liste mit den Zeilen erstellt, die aus der Datei in umgekehrter Reihenfolge gelesen wurden (da Sie sich an den Kopf der Liste angemeldet haben) und dann nichts damit getan haben.

Wenn Sie etwas damit anfangen möchten, ändern Sie die "return () in" Rückgabeliste ". Die Rückgabe erzeugt einen Wert des Typs "IO [String], wobei die Liste darin (Rückgabe ist nichts anderes als das Einkapselung des Werts), den Sie an Loadnums mit der <-Syntax extrahieren können.

Der Rest bleibt dem Leser als Übung.

Andere Tipps

Wenn dies nicht für Hausaufgaben oder so ist, gibt es keinen Grund, so viel Mühe zu verwenden. Wiederverwendung ist faul!

getLines = liftM lines . readFile

main = do
    list <- getLines "dictionary.txt"
    mapM_ putStrLn list

Aber wenn Sie noch Haskell zu lernen scheinen, ist es für Sie wichtig zu verstehen, was Cesarb geschrieben hat.

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