上手く書けなかった

議席数をドント方式で

動くには動くというだけ。

import List

type PartyNumber = Int

numberOfSeat = 100
numberOfVotes = [123, 4, 56, 78]

main = do print $ result
            $ numberOfWinners $ (winners numberOfSeat) $ concat
            $ markedDhondtTable $ dhondtTable numberOfVotes numberOfSeat

result :: [(PartyNumber, Int)] -> [Int]
result xs = map (numberOfWinnersAtPartyNumber xs) [1..length numberOfVotes]

-- 政党番号に対応した当選数
numberOfWinnersAtPartyNumber :: [(PartyNumber, Int)] -> PartyNumber -> Int
numberOfWinnersAtPartyNumber xs n =
  let numberOfWinner = filter ((\a (b, c) -> a == b)(n)) xs
  in if numberOfWinner /= [] then (snd.head) numberOfWinner else 0

-- 政党番号別当選者数
numberOfWinners :: [(Double, PartyNumber)] -> [(PartyNumber, Int)]
numberOfWinners [] = []
numberOfWinners xs = let top = snd $ head xs
                         exceptTop = filter ((\t (d,n) -> n /= t)(top)) xs
                         nOfw = length xs - length exceptTop
                     in (top, nOfw) : (numberOfWinners exceptTop)

-- 当選者 :: 当選者数 -> 得票リスト -> 当選者得票リスト
winners :: (Ord a) => Int -> [a] -> [a]
winners n xs = take n $ reverse $ List.sort xs

-- ドント表に政党番号を付ける
markedDhondtTable :: [[Double]] -> [[(Double, PartyNumber)]]
markedDhondtTable xs = map markedPartyNumber (zip xs [1..])

-- 政党番号を付ける
markedPartyNumber :: ([Double], PartyNumber) -> [(Double, PartyNumber)]
markedPartyNumber (xs, n) = map ((\n m->(m,n))(n)) xs

-- 得票数と定数からドント表を作成する
dhondtTable :: [Int] -> Int -> [[Double]]
dhondtTable ns n = map (dhondtList n) ns

-- 定数と得票数を元に割った得票数のリストを返す
dhondtList :: Int -> Int -> [Double]
dhondtList seat vote = map (\n -> fromIntegral(vote) / fromIntegral(n)) [1..seat]