user2879704
user2879704

Reputation:

Understand error function's return value type

: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

Answers (2)

gdejohn
gdejohn

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

sepp2k
sepp2k

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

Related Questions