{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE DeriveDataTypeable #-} module Type.Data.Num.Decimal.Digit where import qualified Type.Data.Num.Unary.Literal as UnaryLit import Type.Base.Proxy (Proxy(Proxy)) import Data.Typeable (Typeable) newtype Singleton d = Singleton Int singleton :: (C d) => Singleton d singleton = switch (Singleton 0) (Singleton 1) (Singleton 2) (Singleton 3) (Singleton 4) (Singleton 5) (Singleton 6) (Singleton 7) (Singleton 8) (Singleton 9) class C d where switch :: f Dec0 -> f Dec1 -> f Dec2 -> f Dec3 -> f Dec4 -> f Dec5 -> f Dec6 -> f Dec7 -> f Dec8 -> f Dec9 -> f d class C d => Pos d where switchPos :: f Dec1 -> f Dec2 -> f Dec3 -> f Dec4 -> f Dec5 -> f Dec6 -> f Dec7 -> f Dec8 -> f Dec9 -> f d data Dec0 deriving (Typeable) instance C Dec0 where switch x _ _ _ _ _ _ _ _ _ = x instance Show Dec0 where show _ = "0" data Dec1 deriving (Typeable) instance Pos Dec1 where switchPos x _ _ _ _ _ _ _ _ = x instance C Dec1 where switch _ x _ _ _ _ _ _ _ _ = x instance Show Dec1 where show _ = "1" data Dec2 deriving (Typeable) instance Pos Dec2 where switchPos _ x _ _ _ _ _ _ _ = x instance C Dec2 where switch _ _ x _ _ _ _ _ _ _ = x instance Show Dec2 where show _ = "2" data Dec3 deriving (Typeable) instance Pos Dec3 where switchPos _ _ x _ _ _ _ _ _ = x instance C Dec3 where switch _ _ _ x _ _ _ _ _ _ = x instance Show Dec3 where show _ = "3" data Dec4 deriving (Typeable) instance Pos Dec4 where switchPos _ _ _ x _ _ _ _ _ = x instance C Dec4 where switch _ _ _ _ x _ _ _ _ _ = x instance Show Dec4 where show _ = "4" data Dec5 deriving (Typeable) instance Pos Dec5 where switchPos _ _ _ _ x _ _ _ _ = x instance C Dec5 where switch _ _ _ _ _ x _ _ _ _ = x instance Show Dec5 where show _ = "5" data Dec6 deriving (Typeable) instance Pos Dec6 where switchPos _ _ _ _ _ x _ _ _ = x instance C Dec6 where switch _ _ _ _ _ _ x _ _ _ = x instance Show Dec6 where show _ = "6" data Dec7 deriving (Typeable) instance Pos Dec7 where switchPos _ _ _ _ _ _ x _ _ = x instance C Dec7 where switch _ _ _ _ _ _ _ x _ _ = x instance Show Dec7 where show _ = "7" data Dec8 deriving (Typeable) instance Pos Dec8 where switchPos _ _ _ _ _ _ _ x _ = x instance C Dec8 where switch _ _ _ _ _ _ _ _ x _ = x instance Show Dec8 where show _ = "8" data Dec9 deriving (Typeable) instance Pos Dec9 where switchPos _ _ _ _ _ _ _ _ x = x instance C Dec9 where switch _ _ _ _ _ _ _ _ _ x = x instance Show Dec9 where show _ = "9" reify :: Integer -> (forall d. C d => Proxy d -> w) -> w reify n f = if n==0 then f (Proxy :: Proxy Dec0) else reifyPos n f reifyPos :: Integer -> (forall d. Pos d => Proxy d -> w) -> w reifyPos n f = case n of 1 -> f (Proxy :: Proxy Dec1) 2 -> f (Proxy :: Proxy Dec2) 3 -> f (Proxy :: Proxy Dec3) 4 -> f (Proxy :: Proxy Dec4) 5 -> f (Proxy :: Proxy Dec5) 6 -> f (Proxy :: Proxy Dec6) 7 -> f (Proxy :: Proxy Dec7) 8 -> f (Proxy :: Proxy Dec8) 9 -> f (Proxy :: Proxy Dec9) _ -> error "digit must be a number from 0 to 9" type family ToUnary n type instance ToUnary Dec0 = UnaryLit.U0 type instance ToUnary Dec1 = UnaryLit.U1 type instance ToUnary Dec2 = UnaryLit.U2 type instance ToUnary Dec3 = UnaryLit.U3 type instance ToUnary Dec4 = UnaryLit.U4 type instance ToUnary Dec5 = UnaryLit.U5 type instance ToUnary Dec6 = UnaryLit.U6 type instance ToUnary Dec7 = UnaryLit.U7 type instance ToUnary Dec8 = UnaryLit.U8 type instance ToUnary Dec9 = UnaryLit.U9