Personal tools

Inferring types

From HaskellWiki

Jump to: navigation, search

It is often useful to have the compiler infer types for you automatically. There are a number of ways to do this.

1 GHCi

Load your module in one of the interactive Haskell environments, for example ghci or hugs, and ask it for the type of a top-level declaration in your code:

x = 3
y = "foo"
z = (True, Just ())
main = undefined
 
$ ghci A.hs 
*Main> :t z
z :: (Bool, Maybe ())

2 Editor support

If you use vim, the following script can be used to infer and insert types for you top level declarations:

   #!/bin/sh
   # input is a top level .hs decls
   FILE=$*
   DECL=`cat`
   ID=`echo $DECL | sed 's/^\([^ ]*\).*/\1/'`
   echo ":t $ID" | ghci -v0 -cpp -fglasgow-exts -w $FILE
   echo $DECL

This uses ghci to infer types. With the following .vimrc entry:

   :map ty :.!typeOf %

You can then infer the types of bindings by typing 'ty' with the cursor on the decl whose type you wish to infer. That is:

    y = "foo"

becomes:

    y :: [Char]
    y = "foo"

3 Compiler support

You can have ghc dump the inferred types for you module:

   $ ghc -ddump-tc A.hs 2>&1 | sed '/^\=/d;/AbsBinds/d;/ *\[\]$/d'
    TYPE SIGNATURES
    :Main.main :: IO ()
    main :: forall a. a
    x :: Integer
    y :: [Char]
    z :: (Bool, Maybe ())
 
    main :: forall a. a
    { main = undefined a }
 
    z :: (Bool, Maybe ())
    { z = (GHC.Base.True, Data.Maybe.Just () GHC.Base.()) }
 
    y :: [Char]
    { y = "foo" }
 
    x :: Integer
    { lit_an0 = fromInteger 3
      fromInteger = fromInteger Integer $dNum
      x = 3 }
 
  :Main.main = GHC.TopHandler.runMainIO () (main (IO ()))
  $dNum = GHC.Num.$f3 }