{-# LANGUAGE KindSignatures, TypeInType, TypeFamilies, TypeOperators, UndecidableInstances, RankNTypes, MultiParamTypeClasses, AllowAmbiguousTypes, FlexibleInstances, TypeApplications, ScopedTypeVariables, MagicHash #-} module Clr.TypeString where import Clr.ListTuple import Clr.Types import Data.List(intercalate) import Data.Kind import GHC.TypeLits import GHC.Prim -- -- TString is used to get the runtime value string of a type -- class TString t where tString :: forall t . String -- -- TString instance for (T name gt) -- instance (KnownSymbol name, TString gt) => TString (T name gt) where tString = symbolVal' (proxy# :: Proxy# name) ++ (tString @gt) -- -- TString instance for unit (used as the argument for CLR methods that don't otherwise have arguments) -- instance TString () where tString = "" -- -- TString instance for empty list (used to mean no generic type parameter instantiations) -- instance TString '[] where tString = "" -- -- TSting instance for non-empty list (used for generic type parameter instantiations) -- instance (TString x, TStrings xs, (KnownNat (1 + ListSize xs))) => TString (x ': xs) where tString = "`" ++ show (natVal' (proxy# :: Proxy# (1 + ListSize xs))) ++ "[" ++ intercalate "," (tString @x : tStrings @xs) ++ "]" -- -- TStrings is like TString except it evaluates to a list of strings -- class TStrings ts where tStrings :: forall gt' . [String] instance TStrings '[] where tStrings = [] instance (TString x, TStrings xs) => TStrings (x ': xs) where tStrings = tString @x : tStrings @xs -- -- Property getter / setter methods -- tStringGet :: forall t . (TString t) => String tStringGet = "get_" ++ tString @t tStringSet :: forall t . (TString t) => String tStringSet = "set_" ++ tString @t