-- Condorcet voting. -- Copyright (C) 2005 Evan Martin module Main where import qualified Condorcet import Text.ParserCombinators.Parsec import Control.Monad.Error {- | Parses a simple form of ballots as strings. Ballot strings are comma-separated list in order of preference; equally-ranked candidates are separated with an equals sign. E.g., "3=4=5,1,2" -} parseBallot :: String -> Either ParseError Condorcet.Ballot parseBallot input = parse ballot "" input where ballot :: Parser [[Int]] ballot = do { b <- sepBy1 rank (char ','); eof; return b } rank :: Parser [Int] rank = sepBy1 number (char '=') number :: Parser Int number = do { ds <- many1 digit; return (read ds) } -- parse a set of ballots, halting on failure (using the Error monad). parseBallots :: [String] -> Either String [Condorcet.Ballot] parseBallots bs = mapM pb bs >>= return where pb ballot = case parseBallot ballot of Left err -> throwError (show err) Right x -> return x main :: IO () main = do case parseBallots ["1,2,3", "2=1,3", "2,1,3"] of Left e -> putStrLn e Right ballots -> do putStrLn $ "Parsed " ++ (show (length ballots)) ++ " ballots:" mapM_ print ballots putStrLn "Computing winners..." let winners = Condorcet.run ballots putStrLn "Winners:" putStrLn $ show winners -- vim: set ts=2 sw=2 et :