module Currency.Rates where

import Prelude hiding (lookup)
import Data.Map (Map, empty, lookup, insert)

-- | A map from currency to exchange rate against some reference currency
data Rates a b = Rates {
		reference :: a,
		rates :: Map a b
	} deriving (Show, Read, Eq)

-- | Change the reference currency to a different one found in the 'Map'
rebase :: (Ord a, Fractional b) => a -> Rates a b -> Rates a b
rebase new rs@(Rates old m)
	| new == old = rs
	| otherwise = Rates new $ maybe empty
		(\newRate -> fmap (/newRate) $ insert old 1 m) $
		lookup new m

-- | Convenience function for getting a single exchange rate
--
-- If you're doing a lot of conversions, use 'rebase' and 'lookup'
exchangeRate :: (Ord a, Fractional b) =>
	Rates a b
	-> a -- ^ Source currency
	-> a -- ^ Target currency
	-> Maybe b
exchangeRate rs source target = lookup target $ rates (rebase source rs)