module Haspara.TH where
import Data.Function (fix)
import Data.Scientific (Scientific)
import qualified Data.Text as T
import GHC.TypeLits (KnownNat)
import Haspara.Currency (Currency, CurrencyPair (CurrencyPair), mkCurrencyError)
import Haspara.Quantity (Quantity, mkQuantityLossless)
import qualified Language.Haskell.TH as TH
import qualified Language.Haskell.TH.Syntax as TH.Syntax
quantityTH :: KnownNat s => Scientific -> TH.Code TH.Q (Quantity s)
quantityTH :: forall (s :: Nat). KnownNat s => Scientific -> Code Q (Quantity s)
quantityTH = forall a. (a -> a) -> a
fix forall a b. (a -> b) -> a -> b
$ \Scientific -> Code Q (Quantity s)
loop -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a (m :: * -> *). m (TExp a) -> Code m a
TH.Syntax.liftCode forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show) forall t (m :: * -> *). (Lift t, Quote m) => t -> Code m t
TH.Syntax.liftTyped forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (s :: Nat).
KnownNat s =>
Code Q (Quantity s) -> Scientific -> Either String (Quantity s)
quantityWE (Scientific -> Code Q (Quantity s)
loop forall a. HasCallStack => a
undefined)
where
quantityWE :: KnownNat s => TH.Code TH.Q (Quantity s) -> Scientific -> Either String (Quantity s)
quantityWE :: forall (s :: Nat).
KnownNat s =>
Code Q (Quantity s) -> Scientific -> Either String (Quantity s)
quantityWE = forall a b. a -> b -> a
const forall (s :: Nat) (m :: * -> *).
(KnownNat s, MonadError String m) =>
Scientific -> m (Quantity s)
mkQuantityLossless
currencyTH :: T.Text -> TH.Code TH.Q Currency
currencyTH :: Text -> Code Q Currency
currencyTH = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a (m :: * -> *). m (TExp a) -> Code m a
TH.Syntax.liftCode forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack) forall t (m :: * -> *). (Lift t, Quote m) => t -> Code m t
TH.Syntax.liftTyped forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadError Text m => Text -> m Currency
mkCurrencyError
currencyPairTH :: T.Text -> T.Text -> TH.Code TH.Q CurrencyPair
currencyPairTH :: Text -> Text -> Code Q CurrencyPair
currencyPairTH Text
cf Text
ct = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a (m :: * -> *). m (TExp a) -> Code m a
TH.Syntax.liftCode forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack) forall t (m :: * -> *). (Lift t, Quote m) => t -> Code m t
TH.Syntax.liftTyped (Text -> Text -> Either Text CurrencyPair
mkPair Text
cf Text
ct)
where
mkPair :: T.Text -> T.Text -> Either T.Text CurrencyPair
mkPair :: Text -> Text -> Either Text CurrencyPair
mkPair Text
x Text
y = Currency -> Currency -> CurrencyPair
CurrencyPair forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadError Text m => Text -> m Currency
mkCurrencyError Text
x forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *). MonadError Text m => Text -> m Currency
mkCurrencyError Text
y