Ich bin nur ein Anfänger Haskell Programmierer (und die kleine Haskell, die ich gelernt habe, war vor 5 Jahren), aber für den Anfang würde ich die natürliche Übersetzung Ihrer Funktion schreiben, mit dem Akku ("der aktuelle Absatz")) wird herumgereicht (ich habe Typen hinzugefügt, nur für Klarheit):
type Line = String
type Para = [Line]
-- Takes a list of lines, and returns a list of paragraphs
paragraphs :: [Line] -> [Para]
paragraphs ls = paragraphs2 ls []
-- Helper function: takes a list of lines, and the "current paragraph"
paragraphs2 :: [Line] -> Para -> [Para]
paragraphs2 [] para = [para]
paragraphs2 ("":ls) para = para : (paragraphs2 ls [])
paragraphs2 (l:ls) para = paragraphs2 ls (para++[l])
Dies funktioniert:
*Main> paragraphs ["Line 1", "Line 2", "", "Line 3", "Line 4"]
[["Line 1","Line 2"],["Line 3","Line 4"]]
Damit eine Lösung ist. Aber dann schlägt Haskell Erfahrung, dass es fast immer Bibliotheksfunktionen für Dinge wie diese :) Eine verwandte Funktion tun wird groupBy genannt, und es funktioniert fast:
paragraphs3 :: [Line] -> [Para]
paragraphs3 ls = groupBy (\x y -> y /= "") ls
*Main> paragraphs3 ["Line 1", "Line 2", "", "Line 3", "Line 4"]
[["Line 1","Line 2"],["","Line 3","Line 4"]]
Oops. Was wir wirklich brauchen, ist ein „splitBy“, und it's not in the libraries, aber wir können die schlechten uns herauszufiltern:
paragraphs4 :: [Line] -> [Para]
paragraphs4 ls = map (filter (/= "")) (groupBy (\x y -> y /= "") ls)
oder, wenn man cool sein wollen, Sie loszuwerden, das Argument bekommen können und tun es die sinnloser Weg:
paragraphs5 = map (filter (/= "")) . groupBy (\x y -> y /= "")
Ich bin mir sicher es gibt einen noch kürzeren Weg.:-)
bearbeiten: ephemient weist darauf hin, dass (not . null)
sauberer als (/= "")
ist. So können wir
schreiben
paragraphs = map (filter $ not . null) . groupBy (const $ not . null)
Die wiederholten (not . null)
ein starker Hinweis darauf ist, dass wir wirklich sollte abstrakt dies aus in eine Funktion, und das ist, was die Data.List.Split module tut, wie unten in der Antwort darauf hingewiesen.
Haben Sie eine Referenz dafür? Der Haskell 98-Bibliotheksbericht (http://www.cs.auckland.ac.nz/references/haskell/haskell-library-1.4-html/list.html) * sagt * es ist ein Gleichheitsprädikat, gibt aber eine explizite Implementierung von die Funktion groupBy. Beachten Sie, dass die Typ-Signatur von groupBy keine "Eq" -Bedingung hat, was darauf hindeutet, dass sie mit einer beliebigen (transitiven?) Prädikatfunktion arbeiten soll ... Es scheint üblich, sie so zu verwenden: http: //www.haskell .org/haskellwiki/List_function_suggestions # Generalize_groupBy_and_friends – ShreevatsaR
Ich würde 'nicht bevorzugen. null 'to using '(/ =" ")', was zu den noch weiteren point-free' parges = map (Filter $ not. null) führen würde. groupBy (const $ nicht. null) ' – ephemient