Singular Type Constructor
Hal Daume III
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
> \x y -> x ++ " " ++ y
you nicely get back:
[Char] -> [Char] -> [Char]
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
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...
On Mon, 30 Jul 2001, Ashley Yakeley wrote:
> 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'?
> 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
Hal Daume III firstname.lastname@example.org
"arrest this man, he talks in maths" www.andrew.cmu.edu/~hcd