Home About Contact
Haskell

ポケモン名のリストから最も出現頻度の高いポケモンをみつける(Haskell編)

ポケモン名のリストから最も出現頻度の高いポケモンをみつける というエントリーを書きましたが、その内容を Haskell へ移植しました。

あとで、備忘録として移植手順を書き残すつもりですが、今はまずは結果だけメモします。

完成したコード

app/Main.hs

module Main
  ( main
  ) where

import Data.List

type Name = String

data Pokemon =
  Pokemon Name
  deriving (Eq, Show)

type Count = Int

data PokemonAndCount =
  PokemonAndCount Pokemon Count
  deriving (Show)

type Condition = Pokemon -> Bool

getName :: Pokemon -> Name
getName (Pokemon n) = n

getCount :: PokemonAndCount -> Count
getCount (PokemonAndCount _ c) = c

getPokemon :: PokemonAndCount -> Pokemon
getPokemon (PokemonAndCount p _) = p

countif :: [Pokemon] -> Condition -> Count
countif px c = length $ filter c px

toPokemonAndCountList :: [Pokemon] -> [PokemonAndCount]
toPokemonAndCountList px =
  map (\p -> PokemonAndCount p (countif px (sameName p))) uniquePokemonList
  where
    uniquePokemonList = nub px

sortWith :: Ord b => (a -> b) -> [a] -> [a]
sortWith f = sortBy (\x y -> compare (f x) (f y))

toPokemonWithMaxCount :: [Pokemon] -> Pokemon
toPokemonWithMaxCount px =
  last $ map (\pandc -> getPokemon pandc) pokemonAndCountList
  where
    pokemonAndCountList =
      sortWith (\pandc -> getCount pandc) (toPokemonAndCountList px)

--sameName :: Pokemon -> Condition
sameName :: Pokemon -> Pokemon -> Bool
sameName p0 p1 = (getName p0) == (getName p1)

mp :: String -> Pokemon
mp name = Pokemon name

pokemonListA :: [Pokemon]
pokemonListA =
  [ mp "Pikachu"
  , mp "Charamander"
  , mp "Squirtle"
  , mp "Pikachu"
  , mp "Metapod"
  , mp "Pikachu"
  ]

{--
pokemonListB :: [Pokemon]
pokemonListB =
  [ mp "Squirtle"
  , mp "Pikachu"
  , mp "Charamander"
  , mp "Squirtle"
  , mp "Pikachu"
  , mp "Metapod"
  , mp "Pikachu"
  , mp "Squirtle"
  , mp "Squirtle"
  ]
--}

main :: IO ()
main = putStrLn $ show $ toPokemonWithMaxCount pokemonListA
--main = putStrLn $ show $ toPokemonWithMaxCount pokemonListB

実行する:

$ stack run
Pokemon "Pikachu"