module Penny.Lincoln.Bits.Price ( From ( From, unFrom ), To ( To, unTo ), CountPerUnit ( CountPerUnit, unCountPerUnit ), Price ( from, to, countPerUnit ), convert, newPrice) where import qualified Penny.Lincoln.Bits.Open as O import Penny.Lincoln.Bits.Qty (Qty, mult) newtype From = From { unFrom :: O.Commodity } deriving (Eq, Ord, Show) newtype To = To { unTo :: O.Commodity } deriving (Eq, Ord, Show) newtype CountPerUnit = CountPerUnit { unCountPerUnit :: Qty } deriving (Eq, Ord, Show) data Price = Price { from :: From , to :: To , countPerUnit :: CountPerUnit } deriving (Eq, Ord, Show) -- | Convert an amount from the From price to the To price. Fails if -- the From commodity in the Price is not the same as the commodity in -- the Amount. convert :: Price -> O.Amount -> Maybe O.Amount convert p (O.Amount q c sd sb) = if (unFrom . from $ p) /= c then Nothing else let q' = q `mult` (unCountPerUnit . countPerUnit $ p) in Just (O.Amount q' (unTo . to $ p) sd sb) -- | Succeeds only if From and To are different commodities. newPrice :: From -> To -> CountPerUnit -> Maybe Price newPrice f t cpu = if unFrom f == unTo t then Nothing else Just $ Price f t cpu