-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Implementation of the Borda count election method.
--   
--   Implementation of the Borda count election method, optionally with
--   different weights for different participants.
--   
--   See <a>https://en.wikipedia.org/wiki/Borda_count</a>
@package bordacount
@version 0.1.0.0


-- | Implementation of the modified Borda count election method.
--   
--   The implementation implements the modified Borda count election
--   method, optionally with different weights for different participants.
--   
--   See <a>https://en.wikipedia.org/wiki/Borda_count</a>.
--   
--   The election runs in two phases. First individual <a>Vote</a>s on
--   options from a certain participant are gathered and ranked into the
--   participant's <a>Ballot</a> using the function <a>ballot</a>.
--   
--   Then all ballots are gathered and an <a>election</a> is held,
--   resulting in a list of election <a>Result</a>s, one for each option.
--   
--   Except for the <a>Vote</a> data constructor, you should not use other
--   data constructors, as they do not reflect invariants correctly.
--   However, the <a>ballot</a> and <a>election</a> will enforce variants.
module Data.Voting.BordaCount

-- | A vote is an attribution of a number of points to an option
data Vote o
Vote :: Int -> o -> Vote o
[voteRanking] :: Vote o -> Int
[voteOption] :: Vote o -> o

-- | A ballot with options of type <tt>o</tt> filled in by a participant of
--   type <tt>p</tt>.
data Ballot p o
Ballot :: p -> [Vote o] -> Ballot p o
[ballotParticipant] :: Ballot p o -> p
[ballotVotes] :: Ballot p o -> [Vote o]

-- | Errors that can occur when creating a <a>Ballot</a> using
--   <a>ballot</a>.
data BallotError o

-- | The given options have the same ranking
DuplicateRanking :: o -> o -> BallotError o

-- | The given option was voted on twice.
DuplicateOption :: o -> BallotError o

-- | Construct a new ballot for a participant from a collection of votes.
--   
--   This function constructs a valid ballot or returns an error if the
--   collection of votes is invalid.
ballot :: Eq o => p -> [Vote o] -> Either (BallotError o) (Ballot p o)

-- | Result of a certain option of type <tt>o</tt> of an election.
data Result o
Result :: o -> Score -> Zeros -> Result o

-- | The weighted score of a <a>Result</a>.
newtype Score
Score :: Double -> Score

-- | The number of weighted zeros a <a>Result</a> got.
newtype Zeros
Zeros :: Double -> Zeros

-- | Error that can occur when holding an <a>election</a>.
newtype ElectionError p

-- | The given participant voted twice.
DuplicateParticipant :: p -> ElectionError p

-- | Hold an election, collect all the ballots and produce the
--   <a>Result</a>.
--   
--   This functions assumes that the <a>Ballot</a>s are well formed, as
--   returned by the function <a>ballot</a>.
--   
--   Thee function holds the election, and might return an
--   <a>ElectionError</a> on any irregularity.
election :: (Eq p, Ord o) => (p -> Double) -> [Ballot p o] -> Either (ElectionError p) [Result o]

-- | Hold an <a>election</a>, but with a weight of <tt>1</tt> for all
--   participants.
--   
--   See <a>election</a> for more information.
election' :: (Eq p, Ord o) => [Ballot p o] -> Either (ElectionError p) [Result o]

-- | Find the first duplicates, filtered by a function.
findFirstDuplicateBy :: (a -> a -> Bool) -> [a] -> Maybe (a, a)
instance GHC.Show.Show p => GHC.Show.Show (Data.Voting.BordaCount.ElectionError p)
instance GHC.Classes.Eq p => GHC.Classes.Eq (Data.Voting.BordaCount.ElectionError p)
instance GHC.Show.Show o => GHC.Show.Show (Data.Voting.BordaCount.BallotError o)
instance GHC.Classes.Eq o => GHC.Classes.Eq (Data.Voting.BordaCount.BallotError o)
instance GHC.Show.Show o => GHC.Show.Show (Data.Voting.BordaCount.Result o)
instance GHC.Classes.Eq o => GHC.Classes.Eq (Data.Voting.BordaCount.Result o)
instance GHC.Show.Show Data.Voting.BordaCount.Zeros
instance GHC.Real.Real Data.Voting.BordaCount.Zeros
instance GHC.Classes.Ord Data.Voting.BordaCount.Zeros
instance GHC.Num.Num Data.Voting.BordaCount.Zeros
instance GHC.Classes.Eq Data.Voting.BordaCount.Zeros
instance GHC.Show.Show Data.Voting.BordaCount.Score
instance GHC.Real.Real Data.Voting.BordaCount.Score
instance GHC.Classes.Ord Data.Voting.BordaCount.Score
instance GHC.Num.Num Data.Voting.BordaCount.Score
instance GHC.Classes.Eq Data.Voting.BordaCount.Score
instance (GHC.Show.Show o, GHC.Show.Show p) => GHC.Show.Show (Data.Voting.BordaCount.Ballot p o)
instance (GHC.Classes.Eq o, GHC.Classes.Eq p) => GHC.Classes.Eq (Data.Voting.BordaCount.Ballot p o)
instance GHC.Show.Show o => GHC.Show.Show (Data.Voting.BordaCount.Vote o)
instance GHC.Classes.Eq o => GHC.Classes.Eq (Data.Voting.BordaCount.Vote o)
