How to convert the type signature of a variable to a String?

Hello, it is possible to write module Main(main) where import Dynamic main = putStrLn ( show ( typeOf (f (1::Integer)))) f x = x The output is of course Integer But the typeOf will only work for 'concrete' data types. It will not work for functions. So I can't write main = putStrLn ( show ( typeOf (f))) Thus it is possible to write a function that recognize functions, i.e. functionType arg = case arg of (arg:: a->b) -> "function" So the question is: Is is possible to write a function the gives back a String with the signature of the argument of that function? For example: 'function f' gives the String "a->a" Best regards, Thomas

Mon, 9 Apr 2001 11:52:47 +0200, Pasch, Thomas (ACTGRO)
So the question is: Is is possible to write a function the gives back a String with the signature of the argument of that function?
For example:
'function f' gives the String "a->a"
No. Classes are not powerful enough to "recognize polymorphism". In this form it's not even theoretically consistent: any function can be treated as a function of a more specific type, so the result would be ambiguous (for example f has type Int->Int too, so asking for a type should give "Int->Int" too). The fact that a function can be treated as of more specific types than originally defined is not a problem when the function is used, because interpretations according to possible types agree. But when you want to make a string out of it, they can't agree if they are not trivial: a value can't behave as both strings "a->a" and "Int->Int". In Haskell there are almost no cases where an ambiguity is resolved implicitly, i.e. when one of several correct interpretations is chosen. There are not many ambiguities at all, and they result in compile errors if they arise. -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK

G'day all.
Mon, 9 Apr 2001 11:52:47 +0200, Pasch, Thomas (ACTGRO)
For example:
'function f' gives the String "a->a"
On Sat, Apr 14, 2001 at 08:28:16PM +0000, Marcin 'Qrczak' Kowalczyk wrote: [...]
In this form it's not even theoretically consistent: any function can be treated as a function of a more specific type, so the result would be ambiguous (for example f has type Int->Int too, so asking for a type should give "Int->Int" too).
I think I understand what you're saying, but I'd just like to understand this practically. We know that the most general type of `id' is "a->a". We assume there's a theoretical function: get_the_function_type_of :: a -> String where a can be a function type. Now consider: f :: (String -> String) -> String f g = g (get_the_function_type_of g) The question is: Should `f id' return "a->a" or "String->String"? Cheers, Andrew Bromage

Sun, 15 Apr 2001 14:20:01 +1000, Andrew J Bromage
We know that the most general type of `id' is "a->a". We assume there's a theoretical function:
get_the_function_type_of :: a -> String
where a can be a function type. Now consider:
f :: (String -> String) -> String f g = g (get_the_function_type_of g)
The question is: Should `f id' return "a->a" or "String->String"?
Inside f the variable g has type String->String. It doesn't matter that the expression used to build this argument could be used on another type too: the level of concreteness of the type is not a part of the object having that type, but a property of the variable through which we access it. It would return "String->String" (assuming that get_the_function_type_of was in some sense possible). Any other overloaded function would be also used as for String->String instead of reporting an ambiguity error, where using it for 'id' directly could report an ambiguity error if the instance is not defined uniformly for all types of function arguments and results but depends on a particular choice of them. In other words all instances of an overloaded function must agree on the level to which they examine the type. If one of them doesn't look at a fragment of the type (e.g. function argument), others can't too; if one of them depends on them, the type must be determined in order to make a usage unambiguous. ghc has -fallow-overlapping-instances which relaxes this requirement. It allows fallbacks: when a type doesn't fit to any instance, try to use a more general one. It still doesn't make calls which don't determine that type unambiguous, and doesn't allow to recognize the fact that a variable is polymorphic. It has some strange properties, e.g. importing a module (which defines some instances) can change a valid program into another valid program with a different meaning. -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK
participants (3)
-
Andrew J Bromage
-
Pasch, Thomas (ACTGRO)
-
qrczak@knm.org.pl