Currency.hs
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
module Aftok.Currency where
import qualified Aftok.Currency.Bitcoin as B
import qualified Aftok.Currency.Zcash as Z
import Control.Lens (Iso')
import qualified Text.Show
data Currency a c where
BTC :: Currency B.Address B.Satoshi
ZEC :: Currency Z.Address Z.Zatoshi
instance Eq (Currency a c) where
BTC == BTC = True
ZEC == ZEC = True
instance Show (Currency a c) where
show = \case
BTC -> "BTC"
ZEC -> "ZEC"
data Currency' c = forall a. Currency' (Currency a c)
instance Eq (Currency' c) where
(Currency' BTC) == (Currency' BTC) = True
(Currency' ZEC) == (Currency' ZEC) = True
instance Show (Currency' c) where
show (Currency' c) = show c
data Amount
= forall a c.
Amount
{ currency :: !(Currency a c),
value :: !c
}
class (Eq c, Ord c, Monoid c) => IsCurrency c where
csub :: c -> c -> Maybe c
cscale :: c -> Rational -> Maybe c
_Units :: Iso' c Word64
currency' :: Currency' c
instance IsCurrency B.Satoshi where
csub = B.ssub
cscale (B.Satoshi amt) factor =
let r = toRational amt * factor
in if (r >= 0) then Just (B.Satoshi . round $ r) else Nothing
_Units = B._Satoshi
currency' = Currency' BTC
instance IsCurrency Z.Zatoshi where
csub = Z.zsub
cscale (Z.Zatoshi amt) factor =
let r = toRational amt * factor
in if (r >= 0) then Just (Z.Zatoshi . round $ r) else Nothing
_Units = Z._Zatoshi
currency' = Currency' ZEC