import Data.List -------------------------------------------------------------------------------- -- LifeRPG - RP Reward Calculator -- -- A simple calculator to help decide how to price rewards in LifeRPG. -- -- Instructions: -- -- 1) Fill in the price of your reward in real currency: price = 49.99 -- -- 2) Add high and low "real currency to RP" conversion points below. Additional -- points may be added, but there must be at least two. "Dollar" here can be -- replaced with RealCurrency, Minute, Hour, or Day. It makes no difference, -- but might help clarity. conversionPoints = [ a 10 Dollar reward `should` cost 250 RP , a 50 Dollar reward `should` cost 750 RP , a 100 Dollar reward `should` cost 1000 RP ] -- -- 3) Click the "Run" button below to calculate your reward cost. -- -- Note: I use the term "price" here, but it can just as well be thought of -- as "time" if the reward costs time instead of money. -------------------------------------------------------------------------------- ---- PROGRAM START: DO NOT EDIT THIS ---- main :: IO () main = do let points = sort conversionPoints if length points < 2 then error "Must have 2 or more conversion points." else return () if price < 0 || any (\(x,y) -> x < 0 || y < 0) points then error "All values must be positive." else return () let (lowPoints,highPoints) = partition ((>=) price . fst) points printRP $ calcRP price lowPoints highPoints where printRP rp = do putStr "Your reward should cost: " putStr $ show rp putStrLn " RP!" calcRP :: Float -> [(Float,Float)] -> [(Float,Float)] -> Int calcRP price lowPoints highPoints | null lowPoints = round $ price * (snd . head $ highPoints) / (fst . head $ highPoints) | null highPoints = round $ price * (snd . last $ lowPoints) / (fst . last $ lowPoints) | otherwise = round rpAmount where lowRP = (snd . last) lowPoints lowCurrency = (fst . last) lowPoints highRP = (snd . head) highPoints highCurrency = (fst . head) highPoints rpSlope = (highRP - lowRP) / (highCurrency - lowCurrency) rpAmount = (price - lowCurrency) * rpSlope + lowRP ---- eDSL Helpers ---- data Currency = RealCurrency | Dollar | RP | Minute | Hour | Day reward = "" a :: Float -> Currency -> String -> Float a realCurrency _ _ = realCurrency cost :: Float -> Currency -> Float cost = const should :: Float -> Float -> (Float, Float) should = (,)