
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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~