pinch-0.2.0.1: src/Pinch/Internal/TType.hs
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
-- |
-- Module : Pinch.Internal.TType
-- Copyright : (c) Abhinav Gupta 2015
-- License : BSD3
--
-- Maintainer : Abhinav Gupta <mail@abhinavg.net>
-- Stability : experimental
--
-- Defines the different types Thrift supports at the protocol level.
--
module Pinch.Internal.TType
(
-- * TType
TType(..)
, IsTType(..)
, SomeTType(..)
, ttypeEquality
, ttypeEqT
-- * Tags
, TBool
, TByte
, TDouble
, TInt16
, TInt32
, TEnum
, TInt64
, TBinary
, TText
, TStruct
, TUnion
, TException
, TMap
, TSet
, TList
) where
import Data.Hashable (Hashable (..))
import Data.Typeable ((:~:) (..), Typeable)
-- | > bool
data TBool deriving (Typeable)
-- | > byte
data TByte deriving (Typeable)
-- | > double
data TDouble deriving (Typeable)
-- | > i16
data TInt16 deriving (Typeable)
-- | > i32
data TInt32 deriving (Typeable)
-- | > enum
type TEnum = TInt32
-- | > i64
data TInt64 deriving (Typeable)
-- | > binary
data TBinary deriving (Typeable)
-- | > string
type TText = TBinary
-- | > struct
data TStruct deriving (Typeable)
-- | > union
type TUnion = TStruct
-- | > exception
type TException = TStruct
-- | > map<k, v>
data TMap deriving (Typeable)
-- | > set<x>
data TSet deriving (Typeable)
-- | > list<x>
data TList deriving (Typeable)
-- | Represents the type of a Thrift value.
--
-- Objects of this type are tagged with one of the TType tags, so this type
-- also acts as a singleton on the TTypes. It allows writing code that can
-- enforce properties about the TType of values at compile time.
data TType a where
TBool :: TType TBool -- 2
TByte :: TType TByte -- 3
TDouble :: TType TDouble -- 4
TInt16 :: TType TInt16 -- 6
TInt32 :: TType TInt32 -- 8
TInt64 :: TType TInt64 -- 10
TBinary :: TType TBinary -- 11
TStruct :: TType TStruct -- 12
TMap :: TType TMap -- 13
TSet :: TType TSet -- 14
TList :: TType TList -- 15
deriving (Typeable)
deriving instance Show (TType a)
deriving instance Eq (TType a)
instance Hashable (TType a) where
hashWithSalt s TBool = s `hashWithSalt` (0 :: Int)
hashWithSalt s TByte = s `hashWithSalt` (1 :: Int)
hashWithSalt s TDouble = s `hashWithSalt` (2 :: Int)
hashWithSalt s TInt16 = s `hashWithSalt` (3 :: Int)
hashWithSalt s TInt32 = s `hashWithSalt` (4 :: Int)
hashWithSalt s TInt64 = s `hashWithSalt` (5 :: Int)
hashWithSalt s TBinary = s `hashWithSalt` (6 :: Int)
hashWithSalt s TStruct = s `hashWithSalt` (7 :: Int)
hashWithSalt s TMap = s `hashWithSalt` (8 :: Int)
hashWithSalt s TSet = s `hashWithSalt` (9 :: Int)
hashWithSalt s TList = s `hashWithSalt` (10 :: Int)
-- | Typeclass used to map type-leve TTypes into 'TType' objects. All TType
-- tags are instances of this class.
class Typeable a => IsTType a where
-- | Based on the context in which this is used, it will automatically
-- return the corresponding 'TType' object.
ttype :: TType a
instance IsTType TBool where ttype = TBool
instance IsTType TByte where ttype = TByte
instance IsTType TDouble where ttype = TDouble
instance IsTType TInt16 where ttype = TInt16
instance IsTType TInt32 where ttype = TInt32
instance IsTType TInt64 where ttype = TInt64
instance IsTType TBinary where ttype = TBinary
instance IsTType TStruct where ttype = TStruct
instance IsTType TMap where ttype = TMap
instance IsTType TSet where ttype = TSet
instance IsTType TList where ttype = TList
-- | Used when the 'TType' for something is not known at compile time.
-- Typically, this will be pattern matched inside a case statement and code
-- that depends on the TType will be go there.
data SomeTType where
SomeTType :: forall a. IsTType a => TType a -> SomeTType
deriving Typeable
deriving instance Show SomeTType
-- | Witness the equality of two ttypes.
ttypeEquality :: TType a -> TType b -> Maybe (a :~: b)
ttypeEquality TBool TBool = Just Refl
ttypeEquality TByte TByte = Just Refl
ttypeEquality TDouble TDouble = Just Refl
ttypeEquality TInt16 TInt16 = Just Refl
ttypeEquality TInt32 TInt32 = Just Refl
ttypeEquality TInt64 TInt64 = Just Refl
ttypeEquality TBinary TBinary = Just Refl
ttypeEquality TStruct TStruct = Just Refl
ttypeEquality TMap TMap = Just Refl
ttypeEquality TSet TSet = Just Refl
ttypeEquality TList TList = Just Refl
ttypeEquality _ _ = Nothing
{-# INLINE ttypeEquality #-}
-- | Witness the equality of two TTypes.
--
-- Implicit version of @ttypeEquality@.
ttypeEqT :: forall a b. (IsTType a, IsTType b) => Maybe (a :~: b)
ttypeEqT = ttypeEquality ttype ttype
{-# INLINE ttypeEqT #-}