Difference between revisions of "Type signatures as good style"

From HaskellWiki
Jump to navigation Jump to search
(mention rank n types)
m (Reverted edits by Tomjaguarpaw (talk) to last revision by Lemming)
 
(3 intermediate revisions by 2 users not shown)
Line 6: Line 6:
 
== Answer ==
 
== Answer ==
   
Using explicit type signatures is good style and [[GHC]] with option <code>-Wall</code> warns about missing signatures.
+
Using explicit [[type signature]]s is good style and [[GHC]] with option <code>-Wall</code> warns about missing signatures.
 
Signatures are a good documentation and not all Haskell program readers have a type inference algorithm built-in.
 
Signatures are a good documentation and not all Haskell program readers have a type inference algorithm built-in.
 
There are also some cases where the infered signature is too general for your purposes.
 
There are also some cases where the infered signature is too general for your purposes.
Line 19: Line 19:
 
Where <hask>ShowS</hask> is <hask>String -> String</hask> rather than <hask>a -> a</hask>.
 
Where <hask>ShowS</hask> is <hask>String -> String</hask> rather than <hask>a -> a</hask>.
   
''I remember that for some type extensions the automatic inference fails. Examples?''
+
Even more, for some type extensions the automatic inference fails,
 
e.g. the higher-order types used by <hask>Control.Monad.ST.runST</hask>
 
Higher-order types, e.g., the type of <hask>Control.Monad.ST.runST</hask>:
 
 
<haskell>
 
<haskell>
 
runST :: (forall s . ST s a) -> a
 
runST :: (forall s . ST s a) -> a

Latest revision as of 15:18, 6 February 2021

Question

Since Haskell type checkers can automatically derive types of expressions why shall I put explicit type signatures in my programs?

Answer

Using explicit type signatures is good style and GHC with option -Wall warns about missing signatures. Signatures are a good documentation and not all Haskell program readers have a type inference algorithm built-in. There are also some cases where the infered signature is too general for your purposes. E.g. the infered (most general) type for asTypeOf is a -> b -> a, but the purpose of asTypeOf is to unify the types of both operands. The more special signature a -> a -> a is what you want and it cannot be infered automatically. Another example:

emptyString :: ShowS
emptyString = id

Where ShowS is String -> String rather than a -> a.

Even more, for some type extensions the automatic inference fails, e.g. the higher-order types used by Control.Monad.ST.runST

runST :: (forall s . ST s a) -> a

cannot be inferred in general, because the problem is undecidable. In GHC, they are enabled with the language pragma RankNTypes.

How to add a bunch of signatures?

Ok, this convinced me. How can I add all the signatures I did not write so far?

You can start GHCi or Hugs and use the :browse Modulename directive. This will list all type signatures including the infered ones.