{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

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 where
    SomePosMoney :: SSymbol c -> PosMoney c -> SomePosMoney

fromPosMoney :: SSymbol s -> PosMoney s -> SomePosMoney
fromPosMoney = SomePosMoney

fromPosMoney' :: (KnownSymbol s) => PosMoney s -> SomePosMoney
fromPosMoney' = SomePosMoney symbolSing

mkSomePosMoney :: String -> Pos -> SomePosMoney
mkSomePosMoney currency amount =
    withSomeSSymbol currency $ \(ss :: SSymbol s) -> SomePosMoney ss (PosMoney amount)

getCurrency :: SomePosMoney -> String
getCurrency (SomePosMoney s _) = fromSSymbol s