{-# LANGUAGE OverloadedLists #-} module Pokemon.Stats ( Proto(..) , Stat , Stats , attack , defense , speed , precision , specialAttack , specialDefense , index , get , modify ) where import Data.Vector (Vector, (!), (//)) newtype Stat = Stat Int attack :: Stat attack = Stat 0 defense :: Stat defense = Stat 1 speed :: Stat speed = Stat 2 precision :: Stat precision = Stat 3 specialAttack :: Stat specialAttack = Stat 4 specialDefense :: Stat specialDefense = Stat 5 data Proto = Proto { attack_ :: Int , defense_ :: Int , speed_ :: Int , precision_ :: Int , specialAttack_ :: Int , specialDefense_ :: Int } newtype Stats = Stats (Vector Int) index :: Proto -> Stats index proto = Stats [ (attack_ proto) , (defense_ proto) , (speed_ proto) , (precision_ proto) , (specialAttack_ proto) , (specialDefense_ proto) ] get :: Stats -> Stat -> Int get (Stats v) (Stat s) = v ! s modify :: Stat -> (Int -> Int) -> Int -> Stats -> Maybe Stats modify stat@(Stat s) f threshold stats@(Stats v) = let result = f $ stats `get` stat in if result < threshold then Nothing else Just . Stats $ v // [(s, result)]