Haskell: A simple parsing example using pattern matching
As part of the second question in the Google Code Jam I needed to be able to parse lines of data which looked like this:
3 1 5 15 13 11
The first integer will be N, the number of Googlers, and the second integer will be S, the number of surprising triplets of scores. The third integer will be p, as described above. Next will be N integers ti: the total points of the Googlers.
This seemed like it should be easy to do but my initial search led me to the Parsec chapter in Real World Haskell which seemed a bit over the top for my problem.
All we really need to do is split on a space and then extract the parts of the resulting list.
I thought there’d be a ‘split’ function to do that in the base libraries but if there is I couldn’t see it.
However, there are a bunch of useful functions in the ‘Data.List.Split’ module which we can install using cabal - a RubyGems like tool which came with my Haskell installation.
Installing the split module was as simple as:
cabal update cabal install split
There’s a list of all the packages available through cabal here.
I needed the splitOn function:
import Data.List.Split > :t splitOn splitOn :: Eq a => [a] -> [a] -> [[a]]
We can then split on a space and extract the appropriate values using pattern matching like so:
let (_:surprisingScores:p:googlers) = map (\x -> read x :: Int) $ splitOn " " "3 1 5 15 13 11"
> surprisingScores 1
> p 5
> googlers [15,13,11]