{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE GADTs #-}
module Money where
import Data.Kind
import Data.Pos
import GHC.TypeLits
-- | Store a positive monetary value
newtype PosMoney (c :: Symbol) = PosMoney {unPosMoney :: Pos}
deriving (Show)
-- data SomePosMoney = forall c. KnownSymbol c => SomePosMoney (PosMoney c)
data SomePosMoney where
SomePosMoney :: KnownSymbol c => PosMoney c -> SomePosMoney
-- is ^this equivalent to the below?
data SomePosMoney' :: Type where
MkSomePosMoney' :: SSymbol s -> PosMoney s -> SomePosMoney'
fromPosMoney :: SSymbol s -> PosMoney s -> SomePosMoney'
fromPosMoney = MkSomePosMoney'
fromPosMoney' :: KnownSymbol s => PosMoney s -> SomePosMoney'
fromPosMoney' = MkSomePosMoney' symbolSing
mkSomePosMoney :: String -> Pos -> SomePosMoney
-- mkSomePosMoney currency amount = withSomeSSymbol currency $ \(ss :: SSymbol s) -> withKnownSymbol ss (mkSomeMoney @s amount)
-- mkSomePosMoney currency amount = withSomeSSymbol currency $ \ss -> mkSomeMoney ss amount
mkSomePosMoney currency amount =
withSomeSSymbol currency $ \(ss :: SSymbol s) ->
withKnownSymbol ss (SomePosMoney @s (PosMoney amount))
-- mkSomePosMoney currency amount = withSomeSSymbol currency $ \ss -> withKnownSymbol ss (SomePosMoney (PosMoney amount))
-- mkSomeMoney :: forall (c :: Symbol). Pos -> SomePosMoney
-- mkSomeMoney :: forall c. KnownSymbol c => Pos -> SomePosMoney
-- mkSomeMoney = SomePosMoney @c . PosMoney
-- mkSomeMoney :: forall (c :: Symbol). SSymbol c -> Pos -> SomePosMoney
-- mkSomeMoney ss amount = withKnownSymbol ss $ SomePosMoney @c (PosMoney amount)
getCurrency :: SomePosMoney -> String
getCurrency (SomePosMoney m) = symbolVal m
getCurrency' :: SomePosMoney' -> String
getCurrency' (MkSomePosMoney' s m) = withKnownSymbol s $ symbolVal m
-- getCurrency (SomePosMoney SSymbol) = fromSSymbol $ symbolSing
-- mkMoney :: SomeSymbol -> Int -> Income c
-- mkMoney = undefined