I will answer the question as it is. Haskell erases all type information during compile time, mostly for efficiency reasons. By default, when a polymorphic function is called, e.g. f :: a->a, no type information is available, and f has no way to know what a actually is -- in this case, f can only be the identity function, fail to terminate, or raise an error.
For the rare cases where type information is needed, there is Typeable. A polymorphic function having type f :: Typeable a => ... is passed a run-time description of the type a, allowing it to test it. Essentially, the Typeable a constraint forces Haskell to keep the runtime information until run time. Note that such type information must be known at the call site -- either because f is called with a completely known type, or because f is called with a partially known type (say f x with x :: Maybe b) but there are suitable Typeable constraints in scope (Typeable b, in the previous example).
Anyway, here's an example:
{-# LANGUAGE TypeApplications, ScopedTypeVariables, GADTs #-}
import Data.Typeable
tostring :: forall b. (Show b, Typeable b) => b -> String
tostring x = case eqT @b @String of -- if b==String
Just Refl -> x -- then
Nothing -> show x -- else
Note how we were able to return x in the "then" branch, since there it is known to be a String.
Data.Typeable) - but there's no reason to do that.data Foo a = FooStr String | FooOther aand use it liketostring :: Show a => Foo a -> String- pattern match on constructornewtype MyString = MyString String,instance Show MyString where show (MyString x) = ....