Personal tools

Determining the type of an expression

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
 
(newlines)
 
(2 intermediate revisions by one user not shown)
Line 54: Line 54:
 
  \f -> map (asTypeOf id f) "Text" :: (Char -> Char) -> [Char]
 
  \f -> map (asTypeOf id f) "Text" :: (Char -> Char) -> [Char]
 
</haskell>
 
</haskell>
 +
 +
=== 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 <hask>Data.Typeable.typeOf</hask> on the value inside SomeException:
 +
 +
<haskell>
 +
λ> 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
 +
</haskell>
 +
  
 
[[Category:FAQ]]
 
[[Category:FAQ]]

Latest revision as of 08:00, 2 May 2018

Contents

[edit] 1 Problem

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


[edit] 2 Solution

[edit] 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.

[edit] 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]

[edit] 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