Last active
January 12, 2020 04:11
-
-
Save olligobber/159ad9cb6362151efb3e6e9d3693ad91 to your computer and use it in GitHub Desktop.
Use of Haskell's type checker for calculations of rates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE TypeOperators #-} | |
import Rates | |
data Second | |
data GP | |
data NatRune | |
data LawRune | |
data AddyArrowBought | |
data AddyArrowShot | |
data OgressKill | |
data OgressDamage | |
data LawDrop | |
data NatDrop | |
ogressHP :: OgressDamage // OgressKill | |
ogressHP = Rate 82 | |
rapidFireRate :: AddyArrowShot // Second | |
rapidFireRate = Rate 1.8 | |
ogressLawDrop :: OgressKill // LawDrop | |
ogressLawDrop = Rate 16.57 | |
ogressNatDrop :: OgressKill // NatDrop | |
ogressNatDrop = Rate 16.57 | |
ogressNatAmount :: NatRune // NatDrop | |
ogressNatAmount = Rate 11.5 | |
ogressLawAmount :: LawRune // LawDrop | |
ogressLawAmount = Rate 11.5 | |
telegrab :: NatRune // LawRune | |
telegrab = Rate 4 | |
arrowCost :: GP // AddyArrowBought | |
arrowCost = Rate 80 | |
-- 20% of arrows are lost when shot | |
shoot :: AddyArrowShot // AddyArrowBought | |
shoot = Rate 5 | |
natPerKill :: NatRune // OgressKill | |
natPerKill = (telegrab &* ogressLawAmount &/ ogressLawDrop) <> (ogressNatAmount &/ ogressNatDrop) | |
gpPerKill :: (OgressDamage // Second) -> (GP // OgressKill) | |
gpPerKill dps = arrowCost &/ shoot &* rapidFireRate &/ dps &* ogressHP | |
gpPerNat :: (OgressDamage // Second) -> (GP // NatRune) | |
gpPerNat dps = gpPerKill dps &/ natPerKill | |
main :: IO () | |
main = do | |
putStrLn "Enter DPS" | |
dps <- Rate . toRational <$> (readLn :: IO Double) | |
putStrLn "GP Per Nat Rune is" | |
print (fromRational $ getVal $ gpPerNat dps :: Double) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE TypeOperators, ExplicitNamespaces #-} | |
module Rates ( | |
Rate(..), | |
(&*), | |
rev, | |
(&/), | |
RatRate, | |
type (//) | |
) where | |
import Data.Semigroup (stimes) | |
newtype Rate a b x = Rate { getVal :: x } | |
instance Functor (Rate a b) where | |
fmap f = Rate . f . getVal | |
instance Applicative (Rate a b) where | |
pure = Rate | |
(<*>) = fmap . getVal | |
instance Monad (Rate a b) where | |
(>>=) = flip ($) . getVal | |
instance Num x => Semigroup (Rate a b x) where | |
(<>) = fmap . (+) . getVal | |
stimes = fmap . (*) . fromIntegral | |
instance Num x => Monoid (Rate a b x) where | |
mempty = Rate 0 | |
infixl 7 &* | |
infixl 7 &/ | |
(&*) :: Num x => Rate a b x -> Rate b c x -> Rate a c x | |
a &* b = Rate $ getVal a * getVal b | |
rev :: Fractional x => Rate a b x -> Rate b a x | |
rev = Rate . recip . getVal | |
(&/) :: Fractional x => Rate a b x -> Rate c b x -> Rate a c x | |
a &/ b = a &* rev b | |
type RatRate a b = Rate a b Rational | |
type a // b = RatRate a b |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment