Singular Type Constructor

Hal Daume III hal@cmu.edu
Thu, 9 Aug 2001 02:00:27 -0400 (EDT)


Just for fun, I was fooling around with this, so that I could get an
instance of Show for functions.  I have something like:

--
data T a = T

class TypeName t where
    typeName :: T t -> String

instance TypeName Char    where typeName T = "Char"
instance TypeName Int     where typeName T = "Int"
instance TypeName Bool    where typeName T = "Bool"
instance TypeName ()      where typeName T = "()"

instance TypeName a => TypeName [a] where
    typeName T = "[" ++ typeName (T :: T a) ++ "]"

instance (TypeName a, TypeName b) => TypeName (a -> b) where
    typeName T = typeName (T :: T a) ++ " -> " ++ typeName (T :: T b)

instance (TypeName a, TypeName b) => Show (a -> b) where
    show f = typeName (T :: T (a -> b))

instance (TypeName a, TypeName b) => TypeName (a,b) where
    typeName T = "(" ++ typeName (T :: T a) ++ ", " ++ typeName (T :: T
b) ++ ")"
--

so if you load this all up and enter, at the ghci prompt, something
like:

> \x y -> x ++ " " ++ y

you nicely get back:
[Char] -> [Char] -> [Char]

Yay!

But suppose you do:

> \x y -> x ++ y

you get back:

Ambiguous type variable(s) `a' in the constraint `TypeName a'
arising from use of `print' at <No locn>
in a `do' expression pattern binding: print it

which is obviously because it can't find an instance of TypeName a for
this type variable.

however, if you try something like:

instance TypeName a where
    typeName T = "??"

it will complain because there must be one non-type variable in the
instance head.

moreover, even if this restriction is removed (anyone know what it's
there for?), there will be the problem of overlapping instances with,
say TypeName Char and TypeName a.

so i'm wondering if there is a way to specify something like:

instance Not (TypeName a) => TypeName a where ...

that is, this type variable a matches with all a such that a is not an
instance of TypeName...

there are other places where i would find such a thing
useful/interesting beyond this TypeName foo, but this seemed like a
good, simple way to explain it...

thanks!

 - Hal

On Mon, 30 Jul 2001, Ashley Yakeley wrote:

> Consider:
>
> --
> data T a = T
> --
>
> Is there anything in the Prelude or a standard library that looks like
> this? Should there be? What should it be called? 'Singleton'? 'Reified'?
> 'T'?
>
> I looked but couldn't find anything. Such a simple type constructor is in
> fact very useful when you need to pass types around to disambiguate class
> instances. For instance:
>
> --
> class HasTypeName t where
> 		getTypeName		:: T t -> String
>
> instance HasTypeName Int where
> 		getTypeName T = "Int"
>
> instance HasTypeName () where
> 		getTypeName T = "()"
>
> intName = getTypeName (T :: T Int)
> --
>
>
> --
> Ashley Yakeley, Seattle WA
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hal Daume III                                                  hal@cmu.edu
"arrest this man, he talks in maths"               www.andrew.cmu.edu/~hcd
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~