# Determining the type of an expression

## 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:

``` Prelude> :type map fromEnum "Text"
map fromEnum "Text" :: [Int]```

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:
`Data.Typeable > catch (openFile "foo" WriteMode >> openFile "foo" WriteMode >> print "opened twice") (\(SomeException e) -> print(typeOf e))`