Personal tools

GHC/Type system

From HaskellWiki

< GHC(Difference between revisions)
Jump to: navigation, search
(Type signatures and ambiguity)
Line 5: Line 5:
   
 
== Type signatures and ambiguity ==
 
== Type signatures and ambiguity ==
  +
  +
It's quite common for people to write a function definition without a type signature, load it into GHCi, use <tt>:t</tt> to see what type it has, and then cut-and-paste that type into the source code as a type signature. Usually this works fine, but alas not always. Perhaps this is a deficiency in GHC, but here's one way it can happen:
  +
<haskell>
  +
class C a b where
  +
foo :: a -> b
  +
  +
konst :: a -> Bool
  +
konst x = True
  +
  +
f :: (C a b) => a -> Bool
  +
f x = konst (foo x)
  +
</haskell>
  +
If you comment out the type signature <hask>f :: (C a b) => a -> Bool</hask>, the module will load fine into GHCi, and <tt>:t</tt> will report exactly this type for <tt>f</tt>. But if you leave the type signature in, you'll get this error:
  +
<pre>
  +
Foo1.hs:12:13:
  +
Could not deduce (C a b1) from the context (C a b)
  +
arising from use of `foo' at Foo1.hs:12:13-17
  +
Possible fix: add (C a b1) to the type signature(s) for `f'
  +
In the first argument of `konst', namely `(foo x)'
  +
In the expression: konst (foo x)
  +
In the definition of `f': f x = konst (foo x)
  +
</pre>
  +
What's going on? Without the type signature, GHC picks a type for <tt>x</tt>, say <tt>x::a</tt>. Then applying <tt>foo</tt> means GHC must pick a return type for <tt>foo</tt>, say <tt>b</tt>, and generates the type constraint <tt>(C a b)</tt>. The function <tt>konst</tt> just discards its argument, so nothing further is known abouut <tt>b</tt>. So GHC ends up saying that <hask>f :: (C a b) => a -> Bool</hask>.
  +
  +
This is probably a very stupid type. Suppose you called <tt>f</tt> thus: <tt>(f 'a')</tt>. Then you'd get a constraint <tt>(C Char b)</tt> where nothing is known about <tt>b</tt>. That would be OK if there was an instance like:
  +
<haskell>
  +
instance C Char b where ...
  +
</haskell>
   
 
== Overlapping instances ==
 
== Overlapping instances ==

Revision as of 14:25, 20 February 2007

Type system extensions in GHC

GHC comes with a rather large collection of type-system extensions (beyond Haskell 98). They are all documented in the user manual, but this page is a place to record observations, notes, and suggestions on them.

Contents

1 Type signatures and ambiguity

It's quite common for people to write a function definition without a type signature, load it into GHCi, use :t to see what type it has, and then cut-and-paste that type into the source code as a type signature. Usually this works fine, but alas not always. Perhaps this is a deficiency in GHC, but here's one way it can happen:

class C a b where
  foo :: a -> b
 
konst :: a -> Bool
konst x = True
 
f :: (C a b) => a -> Bool
f x = konst (foo x)
If you comment out the type signature
f :: (C a b) => a -> Bool
, the module will load fine into GHCi, and :t will report exactly this type for f. But if you leave the type signature in, you'll get this error:
Foo1.hs:12:13:
    Could not deduce (C a b1) from the context (C a b)
      arising from use of `foo' at Foo1.hs:12:13-17
    Possible fix: add (C a b1) to the type signature(s) for `f'
    In the first argument of `konst', namely `(foo x)'
    In the expression: konst (foo x)
    In the definition of `f': f x = konst (foo x)
What's going on? Without the type signature, GHC picks a type for x, say x::a. Then applying foo means GHC must pick a return type for foo, say b, and generates the type constraint (C a b). The function konst just discards its argument, so nothing further is known abouut b. So GHC ends up saying that
f :: (C a b) => a -> Bool
.

This is probably a very stupid type. Suppose you called f thus: (f 'a'). Then you'd get a constraint (C Char b) where nothing is known about b. That would be OK if there was an instance like:

instance C Char b where ...

2 Overlapping instances

Here an interesting message about the interaction of existential types and overlapping instances.

3 Indexed data types and indexed newtypes

Indexed data types (including associated data types) are a very recent addition to GHC's type system extensions that is not yet included in the user manual. To use the extension, you need to obtain a version of GHC from its source repository.

4 Stand-alone deriving clauses

Bjorn Bringert has recently implemented "stand-alone deriving" declarations.