[Haskell-beginners] Re: Parsing a file with data divided into sections

Brent Yorgey byorgey at seas.upenn.edu
Wed Feb 4 09:49:27 EST 2009


On Wed, Feb 04, 2009 at 12:10:02PM +0100, Heinrich Apfelmus wrote:
> Magnus Therning wrote:
> 
> Here's a version using  span  from the Prelude:
> 
>   main = interact $ unlines . map show . countDays . lines
> 
>   countDays []       = []
>   countDays (day:xs) = (day, length people) : countDays xs'
>      where (people, xs') = span (isSpace . head) xs
> 
> 
> Note that this file format is very simple and it's ok to use  lines  and
>  isSpace  to parse it. But the tool of choice are parser combinators
> like  Text.Parsec  or  Text.ParserCombinators.ReadP .

Let me also point out that using the 'split' package from Hackage [1], we
can implement this nicely without any icky manual recursion, and
without resorting to a full-blown parsing library:

  import Data.List.Split
  import Data.Char

  main = interact (unlines . map show . countDays . lines)

  countDays = map length . tail . splitWhen isDay
    where isDay = not . isSpace . head

'splitWhen' splits the list of lines into chunks using things that
satisfy the predicate as delimiters; then we just 'map length' over
those chunks to count the people for each day.  The 'tail' is
necessary because the split actually produces a blank list of people
*before* the first day, but otherwise this is entirely
straightforward.

-Brent

[1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/split


More information about the Beginners mailing list