Reputation:
:t error
shows,
error :: [Char] -> a
To understand, what is the type of a, i wrote this test code,
import Data.Typeable
custom = error "hello how are you"
main = do
let a = custom
putStrLn $ show (typeOf a)
It gets error
function's return value and tries to print it using show
function.
It throws error as,
ab.hs:6:20:
No instance for (Typeable a0) arising from a use of ‘typeOf’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance [overlap ok] Typeable ()
-- Defined in ‘Data.Typeable.Internal’
instance [overlap ok] Typeable Bool
-- Defined in ‘Data.Typeable.Internal’
instance [overlap ok] Typeable Char
-- Defined in ‘Data.Typeable.Internal’
...plus 14 others
How can i do typeOf
for a variable and print it in string form?
Upvotes: 4
Views: 137
Reputation: 7579
a
is lower case, which means it's a type variable. It can take on any type. You can substitute the result of error
for any expression and your code will type check. This is useful for partial functions, which aren't defined for all possible arguments. For example:
head :: [a] -> a
head [] = error "empty list"
head (x:_) = x
Given an empty list, you can't actually produce the first element because it doesn't exist. error
makes the types work out, but blows up at runtime when evaluated.
Per user5402's comment below:
error "add"
can have any type in part because it never returns.
Upvotes: 4
Reputation: 370112
You can't use typeOf
with a polymorphic expression, both because that would be impossible to type in Haskell and because there's no TypeRep
representing type variables. Of course the latter would be easy enough to fix if it were possible to define typeOf
in a way that could ever produce a type variable as its result, which it's not.
Note that if typeOf
could represent type variables and accept polymorphic arguments, typeOf (error "")
would simply print something like "a" or "forall a. a", so I'm not sure that that would help you.
In order to use typeOf
on error
, you'll have to give it a monomorphic type like this typeOf (error "" :: String)
or typeOf (error "" :: Int)
, which will print "String" and "Int" respectively.
Upvotes: 2