2016-04-25 19 views
2

lesen Ich versuche, ein Programm, das Zeile für Zeile aus einer Datei lesen sollte und überprüfen, ob es ein Palindrom ist, wenn es ist, dann drucken.Wie Zeile für Zeile aus einer Datei in Haskell

Ich bin wirklich neu, so dass das einzige, was Haskell ich tun könnte, ist auszudrucken nur jede Zeile, mit diesem Code:

main :: IO() 
    main = do 
    filecontent <- readFile "palindrom.txt" 
    mapM_ putStrLn (lines filecontent) 

isPalindrom w = w==reverse w 

Die Sache ist, ich weiß nicht, wie durch die Linie gehen Linie und Überprüfen Sie, ob die Zeile ein Palindrom ist (beachten Sie, dass in meiner Datei jede Zeile nur ein Wort enthält). Danke für jede Hilfe.

Antwort

3

Schauen Sie sich die filter Funktion an. Sie möchten möglicherweise nicht die gesamte Verarbeitung in eine einzelne Zeile setzen, sondern einen lassen Ausdruck. Auch Ihre Vertiefung ist aus:

main :: IO() 
main = do 
    filecontent <- readFile "palindrom.txt" 
    let selected = filter ... filecontent 
    ... 
+0

können Sie den vollständigen Code schreiben? ich bin absolut neu, also weiß ich nicht, wie man fortfährt. –

2

Hier ist ein Ansatz vorgeschlagenen

main :: IO() 
main = do 
    filecontent <- readFile "palindrom.txt" 
    putStrLn (unlines $ filter isPalindrome $ lines filecontent) 

isPalindrome w = w==reverse w 

Der Teil in Pars ist reiner Code, es hat String->String eingeben. Es ist im Allgemeinen eine gute Idee, reinen Code so weit wie möglich zu isolieren, da dieser Code dazu neigt, am einfachsten zu argumentieren und oft einfacher wiederverwendbar ist.

Sie können sich vorstellen, dass Daten in diesem Abschnitt von rechts nach links fließen und von den Operatoren ($) unterbrochen werden. Zuerst teilen Sie den Inhalt in separate Zeilen auf, filtern dann nur die Palindrome und erstellen schließlich die gesamte Ausgabe als String. Auch weil Haskell faul ist, obwohl es so aussieht, als würde es die Eingabe als eine einzige String im Speicher behandeln, zieht es tatsächlich nur die Daten nach Bedarf.


Edited hinzufügen zusätzliche Informationen ....

OK, also das Herz des Lsg ist der reine Teil:

unlines $ filter isPalindrome $ lines filecontent 

Die Art und Weise, dass ($) Arbeiten ist es, die Funktion Auswertung nach rechts, dann benutze das als Eingabe für das Zeug auf der linken Seite. In diesem Fall ist filecontent die vollständige Eingabe aus der Datei (a String, einschließlich Zeilenvorschubzeichen), und die Ausgabe ist STDOUT (auch eine vollständige Zeichenfolge einschließlich Zeilenvorschubzeichen).

sie Abtastwerteingang durch diesen Prozess folgen "ABCBA \ N1234 \ nk"

unlines $ filter isPalindrome $ lines "abcba\n1234\nK" 

Zuerst Linien werden diese brechen in ein Array von Zeilen

unlines $ filter isPalindrome ["abcba", "1234", "K"] 

anzumerken, dass die Ausgabe von Linien wird in den Eingang für Filter eingespeist.

Also, was macht Filter? Beachten Sie den Typ

filter :: (a -> Bool) -> [a] -> [a] 

Dies dauert 2 Eingang params, die erste ist eine Funktion (die isPalendrome ist), die zweite eine Liste von Elementen. Es wird jedes Element in der Liste mit der Funktion testen, und seine Ausgabe ist die gleiche Listeneingabe minus Elemente, die die Funktion zum Entfernen ausgewählt hat (False zurückgegeben). In unserem Fall sind das erste und dritte Element tatsächlich Palendrome, das zweite nicht.Unser Ausdruck wertet als

unlines ["abcba", "K"] 

Schließlich folgt, unlines das Gegenteil von lines ist .... Es wird die Einzelteile concatinate wieder, Zeilenumbrüchen zwischen einlegen.

"abcba\nK" 

Seit STDIO selbst ein String ist, ist diese bereit zur Ausgabe.

Beachten Sie, dass es völlig in Ordnung, zur Ausgabe eine Liste von String s unter Verwendung von nicht-reinen Funktionen, wie

folgt
forM ["1", "2", "3"] $ \item -> do 
    putStrLn item 

Diese Methode mischt jedoch reinen und unreinen Code, und wird als etwas weniger idiomatische Code Haskell als das Vorherige. Sie werden diese Art von Ding immer noch sehr sehen!

+0

Hallo, danke für Ihre Hilfe, können Sie bitte ein wenig mehr darüber erklären, wie der "$" Operator und der Funktionsfilter arbeiten? Soweit ich verstehe, überprüfen die Filter, ob "isPalindrome" in jeder Zeile der Dateiinhalte, wenn es wahr ist, dann drucken, nicht wahr? Also warum sollte ich hier Linien brauchen? Vielen Dank! –

+1

Ich habe mehr Details hinzugefügt. – jamshidh

+0

Oh großartig! , Danke ! –

Verwandte Themen