Mein Kontext ist Bioinformatik, insbesondere Sequenzierung der nächsten Generation, aber das Problem ist generisch; Daher werde ich eine Protokolldatei als Beispiel verwenden.Haskell: Kann ich mehrere Faltungen über dieselbe faule Liste durchführen, ohne die Liste im Speicher zu behalten?
Die Datei ist sehr groß (Gigabytes groß, komprimiert, so dass es nicht in den Speicher passen wird), ist aber leicht zu analysieren (jede Zeile ein Eintrag), so können wir leicht so etwas wie schreiben:
parse :: Lazy.ByteString -> [LogEntry]
Jetzt habe ich viele Statistiken, die ich aus der Protokolldatei berechnen möchte. Am einfachsten ist es separate Funktionen schreiben wie:
totalEntries = length
nrBots = sum . map fromEnum . map isBotEntry
averageTimeOfDay = histogram . map extractHour
All diese sind von der Form foldl' k z . map f
.
Das Problem ist, dass, wenn ich versuche, sie auf der natürlichste Art und Weise zu verwenden, wie
main = do
input <- Lazy.readFile "input.txt"
let logEntries = parse input
totalEntries' = totalEntries logEntries
nrBots' = nrBots logEntries
avgTOD = averageTimeOfDay logEntries
print totalEntries'
print nrBots'
print avgTOD
Dies wird die gesamte Liste im Speicher zuweisen, das nicht das, was ich will. Ich möchte, dass die Falten synchron gemacht werden, damit die Cons-Zellen Müll gesammelt werden können. Wenn ich nur eine einzige Statistik berechne, passiert das.
Ich kann eine einzelne große Funktion schreiben, die dies tut, aber es ist nicht zusammensetzbaren Code.
Alternativ, was ist, was ich getan habe, ich jeden Durchlauf separat ausführen, aber das & lädt die Datei jedes Mal dekomprimiert.
Warum gehst du nicht machen 'logAnalysers :: [(K, Z, F)]' wo 'K, Z, F' sind die Typen der Funktionen' k, z, f' in Ihrem Beispiel? Dann wird es in gewisser Weise "zusammensetzbarer" Code, wenn Sie eine einzelne Faltung haben, die die Liste verwendet. – dflemstr
@dflemstr die Zwischentypen sind nicht immer die gleichen :( – luispedro
Sie können * logAnalysers :: [forall abc. (B -> c -> b, c, a -> b)] ', die ermöglichen würde verschiedene Typen ... – dflemstr