How to EmptyCase at the type level - haskell

Using EmptyCase, it is possible to implement the following function:
{-# LANGUAGE EmptyCase, EmptyDataDecls #-}
data Void
absurd :: Void -> a
absurd v = case v of
With DataKinds, data types can be promoted to the kind level (their constructors are promoted to type constructors). This works for uninhabited data types like Void as well.
The question here is whether there is a way to write the equivalent of absurd for an uninhabited kind:
tabsurd :: Proxy (_ :: Void) -> a
tabsurd = _
This would effectively be a form of "EmptyCase at the type level". Within reason, feel free to substitute Proxy with some other suitable type (e.g. TypeRep).
NB: I understand that I can just resort to error or similar unsafe techniques here, but I want to see if there's a way to do this that would not work if the type wasn't uninhabited. So for whatever technique we come up with, it should not be possible to use the same technique to inhabit the following function:
data Unit = Unit
notsoabsurd :: Proxy (_ :: Unit) -> a
notsoabsurd = _

The type-level equivalent of pattern-matching is type classes (well, also type families, but they don't apply here, since you want a term-level result).
So you could conceivably make tabsurd a member of a class that has an associated type of kind Void:
class TAbsurd a where
type TAbsurdVoid a :: Void
tabsurd :: a
Here, tabsurd will have type signature tabsurd :: TAbsurd a => a, but if you insist on a Proxy, you can obviously easily convert one to the other:
pabsurd :: TAbsurd a => Proxy a -> a
pabsurd _ = tabsurd
So calling such function or using it in any other way would presumably be impossible, because you can't implement class TAbsurd a for any a, because you can't provide the type TAbsurdVoid a.
According to your requirement, the same approach does work fine for Unit:
data Unit = Unit
class V a where
type VU a :: Unit
uabsurd :: a
instance V Int where
type VU Int = 'Unit
uabsurd = 42
Keep in mind however that in Haskell, any kind (including Void) is potentially inhabited by a non-terminating type family. For example, this works:
type family F a :: x
instance TAbsurd Int where
type TAbsurdVoid Int = F String
tabsurd = 42
However, this limitation is akin to any type (including Void) being inhabited by the value undefined at term level, so that you can actually call absurd like this:
x = absurd undefined
The difference with type level is that you can actually call function tabsurd (given the instance above) and it will return 42:
print (tabsurd :: Int)
This can be fixed by having tabsurd return not a, but a Proxy (TAbsurdVoid a):
class TAbsurd a where
type TAbsurdVoid a :: Void
tabsurd :: Proxy (TAbsurdVoid a)

Related

Haskell: How to write a type of function from a specific type to any type?

In Scala, I could write the following trait:
trait Consumer[A] {
def apply(a: A): Unit
}
And scala would convert whatever I want to Unit, i.e., it would discard the type. Equivalently, I could have said that apply returns Any and ignore the result.
However, in Haskell, if I defined the type as type Consumer = a -> IO (), I wouldn't be able to pass an Int -> IO Int function, as Int isn't ().
There are two ways I know of solving this issue, but none are satisfactory:
Use Data.Functor.void at the call site to manual change IO a to IO (). This is annoying as an API user.
define type Consumer a b = a -> IO b, but then every time I would want to use Consumer in a signature, I would have to carry the useless type b.
Is there any way to define the Consumer type as a function from a to "IO Any"? As far as I know, Haskell does not support something like exists x. a -> IO x.
Using forall results in the opposite of what I want, e.g.,
type Consumer = forall b. a -> IO b
foo :: Int -> IO Int
foo = undefined
bar :: Consumer Int
bar = foo
results in the error:
• Couldn't match type ‘b’ with ‘Int’
‘b’ is a rigid type variable bound by
the type signature for:
bar :: Consumer Int
Expected type: Int -> IO b
Actual type: Int -> IO Int
• In the expression: foo
In an equation for ‘bar’: bar = foo
• Relevant bindings include
bar :: Int -> IO b
Note that I specifically want Consumer to a be type alias, and not a data constructor, as is described here: Haskell function returning existential type. I wouldn't mind if Consumer were a class if anyone knows how to make that work.
To get an existentially-quantified type in Haskell, you need to write down a data declaration (as opposed to a newtype declaration or a type alias declaration, like you used.).
Here's a Consumer type that fits your purposes:
{-# LANGUAGE ExistentialQuantification #-}
data Consumer input = forall output. Consumer { runDiscardingOutput :: input -> IO output }
And, analogously, here is what your example would look like with the new type:
f :: Int -> IO Int
f = undefined
g :: Consumer Int
g = Consumer f
This doesn't really avoid your concerns about client code needing an extra call, though. (I mean, this is no better than exporting a consumer = Data.Functor.void binding from your library.) Also, it complicates how clients will be able to use a consumer, too:
consumer :: Consumer Int
consumer = Consumer (\x -> return [x])
{- This doesn't typecheck -}
main1 :: IO ()
main1 = runIgnoringOutput consumer 4
{- This doesn't typecheck (!!!) -}
main2 :: IO ()
main2 = void (runIgnoringOutput consumer 4)
{- Only this typechecks :( -}
main3 :: IO ()
main3 =
case consumer of
Consumer f -> Data.Functor.void (f 4)
So it would probably make sense to have a apply function in your library that did the dirty work, just as there was an apply function in the Scala library.
apply :: Consumer a -> a -> IO ()
apply (Consumer f) x = void (f x)
I wouldn't mind if Consumer were a class if anyone knows how to make that work.
You can simulate existential types for classes with an associated type family.
But Haskell doesn't allow ambiguous types in classes without using something like a GADT existential wrapper, so you would still have the type information there somewhere.
{-# LANGUAGE TypeFamilies, MultiParamTypeClasses #-}
class Consumer c a where
type Output c
consume :: c -> a -> IO (Output c)
c is necessary here to allow for the reconstruction of the type of Output c, so it is not strictly an existential. But you can now write
{-# LANGUAGE FlexibleInstances, InstanceSigs #-}
instance Consumer (a -> IO b) a where
type Output (a -> IO b) = b
consume :: (a -> IO b) -> a -> IO b
consume = id
This may not fit your use case, because there will not be a type signature that can express Consumer a in a truly existential way. But it is possible to write
... :: (Consumer c a) => c -> ...
(You could also make use of FunctionalDependencies here to clarify the class somewhat.)

Associated type family complains about `pred :: T a -> Bool` with "NB: ‘T’ is a type function, and may not be injective"

This code:
{-# LANGUAGE TypeFamilies #-}
module Study where
class C a where
type T a :: *
pred :: T a -> Bool
— Gives this error:
.../Study.hs:7:5: error:
• Couldn't match type ‘T a’ with ‘T a0’
Expected type: T a -> Bool
Actual type: T a0 -> Bool
NB: ‘T’ is a type function, and may not be injective
The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘Study.pred’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the class method:
Study.pred :: forall a. A a => T a -> Bool
In the class declaration for ‘A’
|
7 | pred :: T a -> Bool
| ^^^^^^^^^^^^^^^^^^^
Replacing type keyword with data fixes.
Why is one wrong and the other correct?
What do they mean by "may not be injective"? What kind of function that is if it is not even allowed to be one to one? And how is this related to the type of pred?
instance C Int where
type T Int = ()
pred () = False
instance C Char where
type T Char = ()
pred () = True
So now you have two definitions of pred. Because a type family assigns just, well, type synonyms, these two definitions have the signatures
pred :: () -> Bool
and
pred :: () -> Bool
Hm, looks rather similar, doesn't it? The type checker has no way to tell them apart. What, then, is
pred ()
supposed to be? True or False?
To resolve this, you need some explicit way of providing the information of which instance the particular pred in some use case is supposed to belong to. One way to do that, as you've discovered yourself, is to change to an associated data family: data T Int = TInt and data T Char = TChar would be two distinguishable new types, rather than synonyms to types, which have no way to ensure they're actually different. I.e. data families are always injective; type families sometimes aren't. The compiler assumes, in the absence of other hints, that no type family is injective.
You can declare a type family injective with another language extension:
{-# LANGUAGE TypeFamilyDependencies #-}
class C a where
type T a = (r :: *) | r -> a
pred :: T a -> a
The = simply binds the result of T to a name so it is in scope for the injectivity annotation, r -> a, which reads like a functional dependency: the result of T is enough to determine the argument. The above instances are now illegal; type T Int = () and type T Char = () together violate injectivity. Just one by itself is admissible.
Alternatively, you can follow the compiler's hint; -XAllowAmbiguousTypes makes the original code compile. However, you will then need -XTypeApplications to resolve the instance at the use site:
pred #Int () == False
pred #Char () == True

Cloud Haskell - How to write "pure" for Closures?

I've been playing with Cloud Haskell. I've noticed in the hackage documentation there's a kind of applicative interface. But in particular I'm trying to find or write a function closurePure with the following signature:
closurePure :: (Typeable a, Binary a) => a -> Closure a
This is basically a restricted version of pure.
Whilst the Closure datatype itself is abstract, the following closure provided:
closure :: Static (ByteString -> a) -> ByteString -> Closure a
So I can get this far:
closurePure :: (Typeable a, Binary a) => a -> Closure a
closurePure x = closure ??? (encode x)
The problem is what to put where the ???s are.
My first attempt was the following:
myDecode :: (Typeable a, Binary a) => Static (ByteString -> a)
myDecode = staticPtr (static decode)
But upon reading the GHC docs on static pointers, the show example suggested to me that you can't have a constraint because a constrained function doesn't have a Typeable instance. So I tried the work around suggested using Dict:
myDecode :: Typeable a => Static (Dict (Binary a) -> ByteString -> a)
myDecode = staticPtr (static (\Dict -> decode))
But now I've got the wrong type that doesn't fit into the closure function above.
Is there anyway to write closurePure or something similar (or have I missed it in the Cloud Haskell docs)? Raising binary plain types to Closures seems essential to using the applicative interface given, but I can't work out how to do it.
Note that I can do this:
class StaticDecode a where
staticPtrDecode :: StaticPtr (ByteString -> a)
instance StaticDecode Int where
staticPtrDecode = static Data.Binary.decode
instance StaticDecode Float where
staticPtrDecode = static Data.Binary.decode
instance StaticDecode Integer where
staticPtrDecode = static Data.Binary.decode
-- More instances etc...
myPure :: forall a. (Typeable a, StaticDecode a, Binary a) => a -> Closure a
myPure x = closure (staticPtr staticPtrDecode) (encode x)
Which works well but basically requires me to repeat an instance for each Binary instance. It seems messy and I'd prefer another way.
You're right, Closure has an applicative-like structure, a fact made even more explicit in both the interface and the implementation of distributed-closure. It's not quite applicative, because in the pure case we do have the additional constraint that the argument must somehow be serializable.
Actually, we have a stronger constraint. Not only must the argument be serializable, but the constraint must itself be serializable. Just like it's hard to serialize functions directly, you can imagine that it's hard to serialize constraints. But just like for functions, the trick is to serialize a static pointer to the constraint itself, if such a static pointer exists. How do we know that such a pointer exists? We could introduce a type class with a single method that gives us the name of the pointer, given a constraint:
class GimmeStaticPtr c where
gimmeStaticPtr :: StaticPtr (Dict c)
There's a slight technical trick going on here. The kind of the type index for StaticPtr is the kind *, whereas a constraint has kind Constraint. So we reuse a trick from the constraints library that consists in wrapping a constraint into a data type (Dict above), which like all data types is of kind *. Constraints that have an associated GimmeStaticPtr instance are called static constraints.
In general, it's sometimes useful to compose static constraints to get more static constraints. StaticPtr is not composable, but Closure is. so what distributed-closure actually does is define a similar class, that we'll call,
class GimmeClosure c where
gimmeClosure :: Closure (Dict c)
Now we can define closurePure in a similar way that you did:
closurePure :: (Typeable a, GimmeClosure (Binary a)) => a -> Closure a
It would be great if in the future, the compiler could resolve GimmeClosure constraints on-the-fly by generating static pointers as needed. But for now, the thing that comes closest is Template Haskell. distributed-closure provides a module to autogenerate GimmeClosure (Cls a) constraints at the definition site for class Cls. See withStatic here.
Incidentally, Edsko de Vries gave a great talk about distributed-closure and the ideas embodied therein.
Let's take a moment to consider what you are asking for. Recall that typeclasses are basically shorthand for dictionary passing. So let's rewrite:
data BinaryDict a = BinaryDict
{ bdEncode :: a -> ByteString
, bdDecode :: ByteString -> a
}
Now you wish to write a function:
closurePure :: (Typeable a) => BinaryDict a -> a -> Closure a
Your attempt is:
closurePure bdict = closure (staticPtr (static (bdDecode bdict))) . bdEncode bdict
Now that we can see what's going on explicitly, we can see that static's argument cannot be closed. If BinaryDicts were allowed to be created willy nilly, say from user data, this function would be impossible. We would instead need:
closurePure :: (Typeable a) => Static (BinaryDict a) -> a -> Closure a
That is, we need entries for the needed Binary instances in the static pointer table. Hence your enumeration solution, and why I suspect that such a solution is required. We also can't expect to enumerate it too automatically, because there are infinitely many instances.
It seems silly to me, however, since instances seem like just the sorts of things that you would want to be static automatically. They are static by nature (what's that, reflection? I can't hear you). This was probably at least ruminated about in the distributed Haskell papers (I haven't read them).
We could solve this problem in general by simply creating a class that concretely enumerates every instance of every class (déjà vu?).
class c => StaticConstraint c where
staticConstraint :: StaticPtr (Dict c)
instance StaticConstraint (Show Int) where
staticConstraint = static Dict
-- a handful more lines...
Somewhat more seriously, if you really don't want to enumerate (I don't blame you), you can at least ease the pain with a calling convention:
closurePure :: (Typeable a, Binary a) => StaticPtr (ByteString -> a) -> a -> Closure a
closurePure decodePtr = closure (staticPtr decodePtr) . encode
someClosure :: Closure Int
someClosure = closurePure (static decode) 42
This nonsense is necessary because static is a "syntactic form" rather than a function -- by mentioning it, we indicate that the Binary instance for Int must actually be generated and recorded in the static pointer table.
If you are feeling cheeky you could enable {-# LANGUAGE CPP #-} and
-- PURE :: (Binary a, Typeable a) => a -> Closure a, I promise
#define PURE (closurePure (static decode))
someClosure :: Closure Int
someClosure = PURE 42
Maybe someday Haskell will take the next step and graduate to the time-tested Segmentation fault (core dumped) of its predecessors instead of spouting off those arrogant type errors.

Defining a Function for Multiple Types

How is a function defined for different types in Haskell?
Given
func :: Integral a => a -> a
func x = x
func' :: (RealFrac a , Integral b) => a -> b
func' x = truncate x
How could they be combined into one function with the signature
func :: (SomeClassForBoth a, Integral b) => a -> b
With a typeclass.
class TowardsZero a where towardsZero :: Integral b => a -> b
instance TowardsZero Int where towardsZero = fromIntegral
instance TowardsZero Double where towardsZero = truncate
-- and so on
Possibly a class with an associated type family constraint is closer to what you wrote (though perhaps not closer to what you had in mind):
{-# LANGUAGE TypeFamilies #-}
import GHC.Exts
class TowardsZero a where
type RetCon a b :: Constraint
towardsZero :: RetCon a b => a -> b
instance TowardsZero Int where
type RetCon Int b = Int ~ b
towardsZero = id
instance TowardsZero Double where
type RetCon Double b = Integral b
towardsZero = truncate
-- and so on
This is known as ad hoc polymorphism, where you execute different code depending on the type. The way this is done in Haskell is using typeclasses. The most direct way is to define a new class
class Truncable a where
trunc :: Integral b => a -> b
And then you can define several concrete instances.
instance Truncable Integer where trunc = fromInteger
instance Truncable Double where trunc = truncate
This is unsatisfying because it requires an instance for each concrete type, when there are really only two families of identical-looking instances. Unfortunately, this is one of the cases where it is hard to reduce boilerplate, for technical reasons (being able to define "instance families" like this interferes with the open-world assumption of typeclasses, among other difficulties with type inference). As a hint of the complexity, note that your definition assumes that there is no type that is both RealFrac and Integral, but this is not guaranteed -- which implementation should we pick in this case?
There is another issue with this typeclass solution, which is that the Integral version doesn't have the type
trunc :: Integral a => a -> a
as you specified, but rather
trunc :: (Integral a, Integral b) => a -> b
Semantically this is not a problem, as I don't believe it is possible to end up with some polymorphic code where you don't know whether the type you are working with is Integral, but you do need to know that when it is, the result type is the same as the incoming type. That is, I claim that whenever you would need the former rather than the latter signature, you already know enough to replace trunc by id in your source. (It's a gut feeling though, and I would love to be proven wrong, seems like a fun puzzle)
There may be performance implications, however, since you might unnecessarily call fromIntegral to convert a type to itself, and I think the way around this is to use {-# RULES #-} definitions, which is a dark scary bag of complexity that I've never really dug into, so I don't know how hard or easy this is.
I don't recommend this, but you can hack at it with a GADT:
data T a where
T1 :: a -> T a
T2 :: RealFrac a => a -> T b
func :: Integral a => T a -> a
func (T1 x) = x
func (T2 x) = truncate x
The T type says, "Either you already know the type of the value I'm wrapping up, or it's some unknown instance of RealFrac". The T2 constructor existentially quantifies a and packs up a RealFrac dictionary, which we use in the second clause of func to convert from (unknown) a to b. Then, in func, I'm applying an Integral constraint to the a which may or may not be inside the T.

Haskell get type of algebraic parameter

I have a type
class IntegerAsType a where
value :: a -> Integer
data T5
instance IntegerAsType T5 where value _ = 5
newtype (IntegerAsType q) => Zq q = Zq Integer deriving (Eq)
newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]
I'm trying to make a nice "show" for the PolyRing type. In particular, I want the "show" to print out the type 'a'. Is there a function that returns the type of an algebraic parameter (a 'show' for types)?
The other way I'm trying to do it is using pattern matching, but I'm running into problems with built-in types and the algebraic type.
I want a different result for each of Integer, Int and Zq q.
(toy example:)
test :: (Num a, IntegerAsType q) => a -> a
(Int x) = x+1
(Integer x) = x+2
(Zq x) = x+3
There are at least two different problems here.
1) Int and Integer are not data constructors for the 'Int' and 'Integer' types. Are there data constructors for these types/how do I pattern match with them?
2) Although not shown in my code, Zq IS an instance of Num. The problem I'm getting is:
Ambiguous constraint `IntegerAsType q'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
In the type signature for `test':
test :: (Num a, IntegerAsType q) => a -> a
I kind of see why it is complaining, but I don't know how to get around that.
Thanks
EDIT:
A better example of what I'm trying to do with the test function:
test :: (Num a) => a -> a
test (Integer x) = x+2
test (Int x) = x+1
test (Zq x) = x
Even if we ignore the fact that I can't construct Integers and Ints this way (still want to know how!) this 'test' doesn't compile because:
Could not deduce (a ~ Zq t0) from the context (Num a)
My next try at this function was with the type signature:
test :: (Num a, IntegerAsType q) => a -> a
which leads to the new error
Ambiguous constraint `IntegerAsType q'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
I hope that makes my question a little clearer....
I'm not sure what you're driving at with that test function, but you can do something like this if you like:
{-# LANGUAGE ScopedTypeVariables #-}
class NamedType a where
name :: a -> String
instance NamedType Int where
name _ = "Int"
instance NamedType Integer where
name _ = "Integer"
instance NamedType q => NamedType (Zq q) where
name _ = "Zq (" ++ name (undefined :: q) ++ ")"
I would not be doing my Stack Overflow duty if I did not follow up this answer with a warning: what you are asking for is very, very strange. You are probably doing something in a very unidiomatic way, and will be fighting the language the whole way. I strongly recommend that your next question be a much broader design question, so that we can help guide you to a more idiomatic solution.
Edit
There is another half to your question, namely, how to write a test function that "pattern matches" on the input to check whether it's an Int, an Integer, a Zq type, etc. You provide this suggestive code snippet:
test :: (Num a) => a -> a
test (Integer x) = x+2
test (Int x) = x+1
test (Zq x) = x
There are a couple of things to clear up here.
Haskell has three levels of objects: the value level, the type level, and the kind level. Some examples of things at the value level include "Hello, world!", 42, the function \a -> a, or fix (\xs -> 0:1:zipWith (+) xs (tail xs)). Some examples of things at the type level include Bool, Int, Maybe, Maybe Int, and Monad m => m (). Some examples of things at the kind level include * and (* -> *) -> *.
The levels are in order; value level objects are classified by type level objects, and type level objects are classified by kind level objects. We write the classification relationship using ::, so for example, 32 :: Int or "Hello, world!" :: [Char]. (The kind level isn't too interesting for this discussion, but * classifies types, and arrow kinds classify type constructors. For example, Int :: * and [Int] :: *, but [] :: * -> *.)
Now, one of the most basic properties of Haskell is that each level is completely isolated. You will never see a string like "Hello, world!" in a type; similarly, value-level objects don't pass around or operate on types. Moreover, there are separate namespaces for values and types. Take the example of Maybe:
data Maybe a = Nothing | Just a
This declaration creates a new name Maybe :: * -> * at the type level, and two new names Nothing :: Maybe a and Just :: a -> Maybe a at the value level. One common pattern is to use the same name for a type constructor and for its value constructor, if there's only one; for example, you might see
newtype Wrapped a = Wrapped a
which declares a new name Wrapped :: * -> * at the type level, and simultaneously declares a distinct name Wrapped :: a -> Wrapped a at the value level. Some particularly common (and confusing examples) include (), which is both a value-level object (of type ()) and a type-level object (of kind *), and [], which is both a value-level object (of type [a]) and a type-level object (of kind * -> *). Note that the fact that the value-level and type-level objects happen to be spelled the same in your source is just a coincidence! If you wanted to confuse your readers, you could perfectly well write
newtype Huey a = Louie a
newtype Louie a = Dewey a
newtype Dewey a = Huey a
where none of these three declarations are related to each other at all!
Now, we can finally tackle what goes wrong with test above: Integer and Int are not value constructors, so they can't be used in patterns. Remember -- the value level and type level are isolated, so you can't put type names in value definitions! By now, you might wish you had written test' instead:
test' :: Num a => a -> a
test' (x :: Integer) = x + 2
test' (x :: Int) = x + 1
test' (Zq x :: Zq a) = x
...but alas, it doesn't quite work like that. Value-level things aren't allowed to depend on type-level things. What you can do is to write separate functions at each of the Int, Integer, and Zq a types:
testInteger :: Integer -> Integer
testInteger x = x + 2
testInt :: Int -> Int
testInt x = x + 1
testZq :: Num a => Zq a -> Zq a
testZq (Zq x) = Zq x
Then we can call the appropriate one of these functions when we want to do a test. Since we're in a statically-typed language, exactly one of these functions is going to be applicable to any particular variable.
Now, it's a bit onerous to remember to call the right function, so Haskell offers a slight convenience: you can let the compiler choose one of these functions for you at compile time. This mechanism is the big idea behind classes. It looks like this:
class Testable a where test :: a -> a
instance Testable Integer where test = testInteger
instance Testable Int where test = testInt
instance Num a => Testable (Zq a) where test = testZq
Now, it looks like there's a single function called test which can handle any of Int, Integer, or numeric Zq's -- but in fact there are three functions, and the compiler is transparently choosing one for you. And that's an important insight. The type of test:
test :: Testable a => a -> a
...looks at first blush like it is a function that takes a value that could be any Testable type. But in fact, it's a function that can be specialized to any Testable type -- and then only takes values of that type! This difference explains yet another reason the original test function didn't work. You can't have multiple patterns with variables at different types, because the function only ever works on a single type at a time.
The ideas behind the classes NamedType and Testable above can be generalized a bit; if you do, you get the Typeable class suggested by hammar above.
I think now I've rambled more than enough, and likely confused more things than I've clarified, but leave me a comment saying which parts were unclear, and I'll do my best.
Is there a function that returns the type of an algebraic parameter (a 'show' for types)?
I think Data.Typeable may be what you're looking for.
Prelude> :m + Data.Typeable
Prelude Data.Typeable> typeOf (1 :: Int)
Int
Prelude Data.Typeable> typeOf (1 :: Integer)
Integer
Note that this will not work on any type, just those which have a Typeable instance.
Using the extension DeriveDataTypeable, you can have the compiler automatically derive these for your own types:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
data Foo = Bar
deriving Typeable
*Main> typeOf Bar
Main.Foo
I didn't quite get what you're trying to do in the second half of your question, but hopefully this should be of some help.

Resources