Difference between revisions of "GHC/Type families"

From HaskellWiki
< GHC
Jump to navigation Jump to search
(How to get indexed types)
 
(GMap class declaration)
Line 6: Line 6:
   
 
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-findexed-types</tt> (or <tt>-fglasgow-exts</tt>, which implies it).
 
Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the [http://www.haskell.org/ghc/dist/current/dist/ nightly snapshots] or in source form from the [http://hackage.haskell.org/trac/ghc/wiki/Building/GettingTheSources source repository]. To enable indexed type families in GHC 6.7, you need to supply the compiler option <tt>-findexed-types</tt> (or <tt>-fglasgow-exts</tt>, which implies it).
  +
  +
== An example ==
  +
  +
As an example, consider Ralf Hinze's [http://www.informatik.uni-bonn.de/~ralf/publications.html#J4 generalised tries], a form of generic finite maps. We define a type class whose instances are the types that we can use as keys in our generic maps:
  +
<haskell>
  +
class GMapKey k where
  +
data GMap k :: * -> *
  +
empty :: GMap k v
  +
lookup :: k -> GMap k v -> Maybe v
  +
insert :: k -> v -> GMap k v -> GMap k v
  +
</haskell>
  +
The interesting part is the ''associated data family'' declaration of the class. It gives a [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html#sec-kinding ''kind signature''] (here <tt>* -> *</tt>) for the associated data type <tt>GMap k</tt> - analog to how methods receive a type signature in a class declaration.
  +
  +
What it is important to notice is that the first parameter of the associated type <tt>GMap</tt> coincides with the class parameter of <tt>GMapKey</tt>. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.
  +
  +
The second important point is that as <tt>GMap k</tt> has kind <tt* -> *</tt> and <tt>k</tt> (implicitly) has kind <tt>*</tt>, the type constructor <tt>GMap</tt> (without an argument) has kind <tt>* -> * -> *</tt>. Consequently, we see that <tt>GMap</tt> is applied to two arguments in the signatures of the methods <tt>empty</tt>, <tt>lookup</tt>, and <tt>insert</tt>.
  +
  +
  +
  +
If you want to play with this example without copying it off the wiki, just download the [http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs source code for <tt>GMap</tt>] from GHC's test suite.

Revision as of 23:39, 24 October 2006

Indexed types families in GHC

Indexed type families are a new addition to GHC's type extensions. They are currently an experimental feature and so their design may still change to some degree. The current implementation covers indexed data types and indexed newtypes, which can either be on the toplevel or inside class declarations, in the form of associated data types. Please not that indexed type synonyms (and hence also associated type synonyms) are not fully implemented yet. Any attempt to use them will lead to strange error messages.

What do I need to use indexed type families?

Indexed type families are implemented in GHC's HEAD (from version 6.7), which you can obtain in binary form from the nightly snapshots or in source form from the source repository. To enable indexed type families in GHC 6.7, you need to supply the compiler option -findexed-types (or -fglasgow-exts, which implies it).

An example

As an example, consider Ralf Hinze's generalised tries, a form of generic finite maps. We define a type class whose instances are the types that we can use as keys in our generic maps:

class GMapKey k where
  data GMap k :: * -> *
  empty       :: GMap k v
  lookup      :: k -> GMap k v -> Maybe v
  insert      :: k -> v -> GMap k v -> GMap k v

The interesting part is the associated data family declaration of the class. It gives a kind signature (here * -> *) for the associated data type GMap k - analog to how methods receive a type signature in a class declaration.

What it is important to notice is that the first parameter of the associated type GMap coincides with the class parameter of GMapKey. This indicates that also in all instances of the class, the instances of the associated data type need to have their first argument match up with the instance type. In general, the type arguments of an associated type can be a subset of the class parameters (in a multi-parameter type class) and they can appear in any order, possibly in an order other than in the class head. The latter can be useful if the associated data type is partially applied in some contexts.

The second important point is that as GMap k has kind <tt* -> * and k (implicitly) has kind *, the type constructor GMap (without an argument) has kind * -> * -> *. Consequently, we see that GMap is applied to two arguments in the signatures of the methods empty, lookup, and insert.


If you want to play with this example without copying it off the wiki, just download the source code for GMap from GHC's test suite.