# Determining the type of an expression

(Difference between revisions)

## 1 Problem

How can I find out the type of an expression or a subexpression?

## 2 Solution

### 2.1 Type of expressions

You can start the interactive environment of Hugs or GHC (GHCi) and use the :type directive:

If the expression is a top-level binding in a module, you can use the :info directive.

Prelude> :info map
map :: (a -> b) -> [a] -> [b]

Using :browse Modulename you can show the types of all top-level variables. This way you can write many functions in a module without a type signature, find them out and add them afterwards. But be warned that due to the Monomorphism restriction the automatically infered signatures are not always the ones you want.

### 2.2 Type of subexpressions

Say, you have the expression
map f "Text" == [1,2,3]
and you want to find out of what type the
f
must be.

This is also possible, just type

Prelude> :type \ f -> map f "Text" == [1,2,3]
\f -> map f "Text" == [1,2,3] :: Num a => (Char -> a) -> Bool
Here
Bool
is the type of
map f "Text" == [1,2,3]
and
Num a => (Char -> a)
is the type of
f
. Now imagine, that the function
f
cannot be chosen freely,

but is an instantiation of a polymorphic function.

E.g. of what concrete type is
id
in
map id "Text"
?
Prelude> :type \ f -> map (id `asTypeOf` f) "Text"
\f -> map (asTypeOf id f) "Text" :: (Char -> Char) -> [Char]

### 2.3 Using Data.Typeable

Say you'd like to catch a specific exception that is thrown, but you don't know which one it is. In the repl, you can catch SomeException and use
Data.Typeable.typeOf
on the value inside SomeException:
λ> import Data.Typeable
λ> let catcher (SomeException e) = print (typeOf e)
λ> let failer = openFile "foo" WriteMode >> openFile "foo" WriteMode >> print "opened twice"
λ> catch failer catcher
IOException