Haskell sometime soon

Way back in October last year (but only 2 entries ago) I posted some Perl code and wrote that I’d post the Haskell sometime soon. Well, that is now; the code is below. I intend to rewrite it to use Parsec at some point, but I haven’t tried that yet since this little hacky script works well enough; and look how long it has taken me to blog it!

module Main where

import Text.XML.HaXml.SAX

data ParserState = FindEntry | FindKeb | FindText

scan :: ParserState -> [SaxElement] -> [String]
scan _ [] = []
scan FindEntry ( (SaxElementOpen "entry" _) : es ) =
    scan FindKeb es
scan FindKeb   ( (SaxElementClose "entry") : es ) =
    "(none)" : (scan FindEntry es)
scan FindKeb   ( (SaxElementOpen "keb" _) : es ) =
    scan FindText es
scan FindText  ( (SaxCharData "\n") : es ) =
    scan FindText es
scan FindText  ( (SaxCharData txt) : es ) =
    txt : (scan FindEntry es)
scan st ( _ : es ) = scan st es

findKebs :: String -> [String]
findKebs i =
    let (es, erc) = saxParse "" i in
    scan FindEntry es

To understand how it works the most important line is the type declaration “scan :: ParserState -> [SaxElement] -> [String]“, which is not actually required by Haskell. From that line we know that “scan” is a function that expects a ParserState as its first parameter and a list of SaxElements as its second parameter, and will then return a list of Strings. Everything else is a simple matter of recursion and pattern matching :-)