# Difference between revisions of "GHC/Type system"

(→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

## 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 ...
```

## Overlapping instances

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

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

## Stand-alone deriving clauses

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