clr-typed-0.2.0: src/Clr/Types.hs
{-# LANGUAGE KindSignatures, TypeInType, TypeFamilies, TypeOperators, UndecidableInstances #-}
module Clr.Types where
import Clr.ListTuple
import Data.Int
import Data.Kind
import Data.Word
import Foreign.Ptr
import GHC.TypeLits
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
--
-- T is the Haskell representation of a type from the CLR, which is a symbol to represent the
-- name, plus zero or more other instances of T that it is instantiated with to implement generics.
--
data T (name::Symbol) (genArgs::[Type])
--
-- MakeT is used to simplify the API so that a Symbol can be used as shorthand to construct a T when
-- generics are not involved, and a promoted tuple of '(Symbol, (Symbol or T)) as shorthand for when they are.
--
type family MakeT (x::k) :: Type where
MakeT (T name gt) = T name gt -- A fully constructed CLR type representation evaluates to itself unchanged
MakeT (name::Symbol) = T name '[] -- A symbol is shorthand for a non-generic type
MakeT '(name, g1) = T name '[MakeT g1] -- A tuple of size n is shorthand for a generic type instantiated with n-1 other types
MakeT '(name, g1, g2) = T name '[MakeT g1, MakeT g2]
MakeT '(name, g1, g2, g3) = T name '[MakeT g1, MakeT g2, MakeT g3]
MakeT '(name, g1, g2, g3, g4) = T name '[MakeT g1, MakeT g2, MakeT g3, MakeT g4]
MakeT '(name, g1, g2, g3, g4, g5) = T name '[MakeT g1, MakeT g2, MakeT g3, MakeT g4, MakeT g5]
MakeT '(name, g1, g2, g3, g4, g5, g6) = T name '[MakeT g1, MakeT g2, MakeT g3, MakeT g4, MakeT g5, MakeT g6]
MakeT '(name, g1, g2, g3, g4, g5, g6, g7) = T name '[MakeT g1, MakeT g2, MakeT g3, MakeT g4, MakeT g5, MakeT g6, MakeT g7]
MakeT '(name, g1, g2, g3, g4, g5, g6, g7, g8) = T name '[MakeT g1, MakeT g2, MakeT g3, MakeT g4, MakeT g5, MakeT g6, MakeT g7, MakeT g8]
MakeT '(name, g1, g2, g3, g4, g5, g6, g7, g8, g9) = T name '[MakeT g1, MakeT g2, MakeT g3, MakeT g4, MakeT g5, MakeT g6, MakeT g7, MakeT g8, MakeT g9]
MakeT '(name, g1, g2, g3, g4, g5, g6, g7, g8, g9, g10) = T name '[MakeT g1, MakeT g2, MakeT g3, MakeT g4, MakeT g5, MakeT g6, MakeT g7, MakeT g8, MakeT g9, MakeT g10]
--
-- Retrieve the name component of a CLR type representation T
--
type family T_GetName (t::Type) :: Symbol where
T_GetName (T name gt) = name
--
-- Retrieve the generic type param component of a CLR type representation T
--
type family T_GetGenT (t::Type) :: [Type] where
T_GetGenT (T name gt) = gt
--
-- Prim types are all values types plus Sytem.String.
-- These are the types that have their own bridge type, everything else is an object reference.
--
type PrimTypes = '[ T "System.String" '[]
, T "System.Boolean" '[]
, T "System.SByte" '[]
, T "System.Byte" '[]
, T "System.Int16" '[]
, T "System.UInt16" '[]
, T "System.Int32" '[]
, T "System.UInt32" '[]
, T "System.Int64" '[]
, T "System.UInt64" '[]
, T "System.IntPtr" '[]
, T "System.UIntPtr" '[]
, T "System.Char" '[]
, T "System.Single" '[]
, T "System.Double" '[]
, T "System.Void" '[] ]
type family IsPrimType (t::Type) :: Bool where
IsPrimType t = t `Elem` PrimTypes
--
-- HaskToClr maps a native Haskell type to the corresponding CLR type.
-- This is an initial stage before the resolver figures out the best implicit
-- conversions to use & overload selection.
type family HaskToClr (h::Type) :: Type
type instance HaskToClr String = T "System.String" '[]
type instance HaskToClr T.Text = T "System.String" '[]
type instance HaskToClr TL.Text = T "System.String" '[]
type instance HaskToClr Bool = T "System.Boolean" '[]
type instance HaskToClr Int8 = T "System.SByte" '[]
type instance HaskToClr Word8 = T "System.Byte" '[]
type instance HaskToClr Int16 = T "System.Int16" '[]
type instance HaskToClr Word16 = T "System.UInt16" '[]
type instance HaskToClr Int32 = T "System.Int32" '[]
type instance HaskToClr Word32 = T "System.UInt32" '[]
type instance HaskToClr Int64 = T "System.Int64" '[]
type instance HaskToClr Word64 = T "System.UInt64" '[]
type instance HaskToClr IntPtr = T "System.IntPtr" '[]
type instance HaskToClr WordPtr = T "System.UIntPtr" '[]
type instance HaskToClr Char = T "System.Char" '[]
type instance HaskToClr Float = T "System.Single" '[]
type instance HaskToClr Double = T "System.Double" '[]
type family HaskToClrL (l::[Type]) :: [Type] where
HaskToClrL '[] = '[]
HaskToClrL (x ': xs) = (HaskToClr x) ': (HaskToClrL xs)
--
-- C# style synonyms
--
type T_sbyte = T "System.SByte" '[]
type T_byte = T "System.Byte" '[]
type T_short = T "System.Int16" '[]
type T_ushort = T "System.UInt16" '[]
type T_int = T "System.Int32" '[]
type T_uint = T "System.UInt32" '[]
type T_long = T "System.Int64" '[]
type T_ulong = T "System.UInt64" '[]
type T_float = T "System.Single" '[]
type T_double = T "System.Double" '[]
type T_decimal = T "System.Decimal" '[]
type T_object = T "System.Object" '[]
type T_string = T "System.String" '[]
type T_char = T "System.Char" '[]
type T_bool = T "System.Boolean" '[]
type T_void = T "System.Void" '[]
--
-- Declaration of all compile type chooseable members of a particular type
--
type family Members (t::Type) :: [Type]
--
-- t `HasMember` m ~ True t has declared m within its members
--
type family HasMember (t::Type) (m::Type) :: Bool where
HasMember t m = m `Elem` (Members t)