https://wiki.haskell.org/api.php?action=feedcontributions&user=Ryantm&feedformat=atomHaskellWiki - User contributions [en]2024-03-29T05:04:15ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=GHC/Stand-alone_deriving_declarations&diff=61298GHC/Stand-alone deriving declarations2016-11-17T18:20:30Z<p>Ryantm: </p>
<hr />
<div>[[Category:GHC|Stand-alone deriving declarations]]<br />
<br />
{{GHCUsersGuide|glasgow_exts|stand-alone-deriving-declarations| a StandaloneDeriving section}}<br />
<br />
''This page is from an early point in the life of the stand-alone deriving mechanism. Please see the linked documentation for an up-to-date account of the present situation.''<br />
<br />
== Standalone deriving ==<br />
<br />
This page mentions points that may not be immediately obvious from the manual.<br />
<br />
== Deriving data types with non-standard contexts ==<br />
<br />
In Haskell 98, and GHC, you can't say this<br />
<haskell><br />
data T m = MkT (m Int) deriving Eq<br />
</haskell><br />
because the instance declaration would have a non-standard context. It would have to look like this:<br />
<haskell><br />
instance Eq (m Int) => Eq (T m) where ...<br />
</haskell><br />
Of course, you can write the instance manually, but then you have to write<br />
all that tiresome code for equality. Standalone deriving lets you supply the context yourself, but have GHC write the code:<br />
<haskell><br />
data T m = MkT (m Int)<br />
deriving instance Eq (m Int) => Eq (T m)<br />
</haskell><br />
Of course, you'll need to add the flags <hask>-XFlexibleContexts</hask> and <hask>-XUndecideableInstances</hask> to allow this instance declaration, but that's fair enough.<br />
<br />
The same applies to data type declarations involving type functions.<br />
<br />
== Variations (not implemented) ==<br />
<br />
This section collects some un-implemented ideas.<br />
<br />
=== Interaction with "newtype-deriving" ===<br />
<br />
GHC's "newtype deriving mechanism" (see [http://www.haskell.org/ghc/dist/current/docs/users_guide/deriving.html#newtype-deriving]) should obviously work in a standalone deriving setting too. But perhaps it can be generalised a little. Currently you can only say<br />
<haskell><br />
deriving instance C a Foo<br />
</haskell><br />
(where Foo is the newtype), and get an instance for <hask>(C a Foo)</hask>. But what if you want and instance for <hask>C Foo a</hask>, where the new type is not the last parameter. You can't do that at the moment. However, even with the new instance-like syntax, it's not clear to me how to signal the type to be derived. Consider<br />
<haskell><br />
newtype Foo = F Int<br />
newtype Bar = B Bool<br />
deriving instance C Foo Bar<br />
</haskell><br />
Which of these thee instances do we want?<br />
<haskell><br />
instance C Foo Bool => C Foo Bar<br />
instance C Int Bar => C Foo Bar<br />
instance C Int Bool => C Foo Bar<br />
</haskell><br />
The obvious way to signal this is to give the instance context (just as above). This is perhaps another reason for having an explicit instance context in a standalone deriving declaration.<br />
<br />
Incidentally, notice that the third of the alternatives in the previous bullet unwraps two newtypes simultaneously. John Meacham suggested this example:<br />
<haskell><br />
class SetLike m k where <br />
instance SetLike IntSet Int where<br />
<br />
newtype Id = Id Int<br />
newtype IdSet = IdSet IntSet<br />
deriving instance SetLike IntSet Int => SetLike IdSet Id<br />
</haskell><br />
<br />
=== Duplicate instances === <br />
<br />
Suppose two modules, M1 and M2 both contain an identical standalone deriving declaration<br />
<haskell><br />
deriving Show T<br />
</haskell><br />
Then, can you import M1 and M2 into another module X and use show on values of type T, or will you get an overlapping instance error? Since both instances are derived in the very same way, their code must be identical, so arguably we can choose either. (There is some duplicated code of course.)<br />
<br />
This situation is expected to be common, as the main use of the standalone feature is to obtain derived instances that were omitted when the data type was defined.<br />
<br />
But, that means whether or not an instance was derived is now part of the module's. Programs would be able to use this (mis)feature to perform a compile-time check and execute code differently depending on whether any given instance is derived or hand-coded:<br />
<haskell><br />
module MA(A) where<br />
data A = A deriving Show<br />
<br />
module MB(B) where<br />
data B = B deriving Show<br />
<br />
module MC where<br />
import MA<br />
import MB<br />
<br />
-- verify that the A and B Show instances were derived<br />
-- (they need to be derived to ensure the output can<br />
-- be parsed in our non-Haskell code).<br />
deriving instance Show A <br />
deriving instance Show B<br />
</haskell><br />
The writer of MC already knows that MA and MB defined instances of Show for A and B. He just wants to ensure that nobody changes either module to use a non-derived instance; if someone does try to use a non-derived instance:<br />
<haskell><br />
module MA(A) where<br />
data A = A<br />
instance Show A where<br />
show _ = "a"<br />
</haskell><br />
then they will get an overlapping instance error in MC. <br />
<br />
The result is that programs would be able to require, for any Class, not just that an instance of the class was defined for a type, but that a /derived/ instance was defined. Is this good?</div>Ryantmhttps://wiki.haskell.org/index.php?title=GHC/Stand-alone_deriving_declarations&diff=61297GHC/Stand-alone deriving declarations2016-11-17T18:20:08Z<p>Ryantm: /* Standalone deriving */</p>
<hr />
<div>[[Category:GHC|Stand-alone deriving declarations]]<br />
<br />
''This page is from an early point in the life of the stand-alone deriving mechanism. Please see the linked documentation for an up-to-date account of the present situation.''<br />
<br />
== Standalone deriving ==<br />
<br />
{{GHCUsersGuide|glasgow_exts|stand-alone-deriving-declarations| a StandaloneDeriving section}}<br />
<br />
This page mentions points that may not be immediately obvious from the manual.<br />
<br />
== Deriving data types with non-standard contexts ==<br />
<br />
In Haskell 98, and GHC, you can't say this<br />
<haskell><br />
data T m = MkT (m Int) deriving Eq<br />
</haskell><br />
because the instance declaration would have a non-standard context. It would have to look like this:<br />
<haskell><br />
instance Eq (m Int) => Eq (T m) where ...<br />
</haskell><br />
Of course, you can write the instance manually, but then you have to write<br />
all that tiresome code for equality. Standalone deriving lets you supply the context yourself, but have GHC write the code:<br />
<haskell><br />
data T m = MkT (m Int)<br />
deriving instance Eq (m Int) => Eq (T m)<br />
</haskell><br />
Of course, you'll need to add the flags <hask>-XFlexibleContexts</hask> and <hask>-XUndecideableInstances</hask> to allow this instance declaration, but that's fair enough.<br />
<br />
The same applies to data type declarations involving type functions.<br />
<br />
== Variations (not implemented) ==<br />
<br />
This section collects some un-implemented ideas.<br />
<br />
=== Interaction with "newtype-deriving" ===<br />
<br />
GHC's "newtype deriving mechanism" (see [http://www.haskell.org/ghc/dist/current/docs/users_guide/deriving.html#newtype-deriving]) should obviously work in a standalone deriving setting too. But perhaps it can be generalised a little. Currently you can only say<br />
<haskell><br />
deriving instance C a Foo<br />
</haskell><br />
(where Foo is the newtype), and get an instance for <hask>(C a Foo)</hask>. But what if you want and instance for <hask>C Foo a</hask>, where the new type is not the last parameter. You can't do that at the moment. However, even with the new instance-like syntax, it's not clear to me how to signal the type to be derived. Consider<br />
<haskell><br />
newtype Foo = F Int<br />
newtype Bar = B Bool<br />
deriving instance C Foo Bar<br />
</haskell><br />
Which of these thee instances do we want?<br />
<haskell><br />
instance C Foo Bool => C Foo Bar<br />
instance C Int Bar => C Foo Bar<br />
instance C Int Bool => C Foo Bar<br />
</haskell><br />
The obvious way to signal this is to give the instance context (just as above). This is perhaps another reason for having an explicit instance context in a standalone deriving declaration.<br />
<br />
Incidentally, notice that the third of the alternatives in the previous bullet unwraps two newtypes simultaneously. John Meacham suggested this example:<br />
<haskell><br />
class SetLike m k where <br />
instance SetLike IntSet Int where<br />
<br />
newtype Id = Id Int<br />
newtype IdSet = IdSet IntSet<br />
deriving instance SetLike IntSet Int => SetLike IdSet Id<br />
</haskell><br />
<br />
=== Duplicate instances === <br />
<br />
Suppose two modules, M1 and M2 both contain an identical standalone deriving declaration<br />
<haskell><br />
deriving Show T<br />
</haskell><br />
Then, can you import M1 and M2 into another module X and use show on values of type T, or will you get an overlapping instance error? Since both instances are derived in the very same way, their code must be identical, so arguably we can choose either. (There is some duplicated code of course.)<br />
<br />
This situation is expected to be common, as the main use of the standalone feature is to obtain derived instances that were omitted when the data type was defined.<br />
<br />
But, that means whether or not an instance was derived is now part of the module's. Programs would be able to use this (mis)feature to perform a compile-time check and execute code differently depending on whether any given instance is derived or hand-coded:<br />
<haskell><br />
module MA(A) where<br />
data A = A deriving Show<br />
<br />
module MB(B) where<br />
data B = B deriving Show<br />
<br />
module MC where<br />
import MA<br />
import MB<br />
<br />
-- verify that the A and B Show instances were derived<br />
-- (they need to be derived to ensure the output can<br />
-- be parsed in our non-Haskell code).<br />
deriving instance Show A <br />
deriving instance Show B<br />
</haskell><br />
The writer of MC already knows that MA and MB defined instances of Show for A and B. He just wants to ensure that nobody changes either module to use a non-derived instance; if someone does try to use a non-derived instance:<br />
<haskell><br />
module MA(A) where<br />
data A = A<br />
instance Show A where<br />
show _ = "a"<br />
</haskell><br />
then they will get an overlapping instance error in MC. <br />
<br />
The result is that programs would be able to require, for any Class, not just that an instance of the class was defined for a type, but that a /derived/ instance was defined. Is this good?</div>Ryantmhttps://wiki.haskell.org/index.php?title=Scoped_type_variables&diff=61295Scoped type variables2016-11-14T00:49:39Z<p>Ryantm: </p>
<hr />
<div>Scoped Type Variables are an extension to Haskell's type system that allow free type variables to be re-used in the scope of a function.<br />
<br />
{{GHCUsersGuide|glasgow_exts|ghc-flag--XScopedTypeVariables|a Scoped Type Variables section}}<br />
<br />
As an example, consider the following functions:<br />
<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables #-}<br />
<br />
...<br />
<br />
mkpair1 :: forall a b. a -> b -> (a,b)<br />
mkpair1 aa bb = (ida aa, bb)<br />
where<br />
ida :: a -> a -- This refers to a in the function's type signature<br />
ida = id<br />
<br />
mkpair2 :: forall a b. a -> b -> (a,b)<br />
mkpair2 aa bb = (ida aa, bb)<br />
where<br />
ida :: b -> b -- Illegal, because refers to b in type signature<br />
ida = id<br />
<br />
mkpair3 :: a -> b -> (a,b)<br />
mkpair3 aa bb = (ida aa, bb)<br />
where<br />
ida :: b -> b -- Legal, because b is now a free variable<br />
ida = id<br />
</haskell><br />
<br />
Scoped type variables make it possible to specify the particular type of a function in situations where it is not otherwise possible, which can in turn help avoid problems with the [[Monomorphism restriction]].<br />
<br />
This feature should be better documented in the Wiki, but this is a start.<br />
<br />
== Avoiding Scoped Type Variables ==<br />
<br />
Although Scoped Type Variables are often a simple solution, they are not available in all compilers.<br />
Often there is a solution that is Haskell 98.<br />
First, there is<br />
<haskell><br />
asTypeOf :: a -> a -> a<br />
asTypeOf a b = a<br />
.<br />
</haskell><br />
It is used like <hask>x `asTypeOf` y</hask> and has the same value like <hask>x</hask>,<br />
but type inference asserts that <hask>x</hask> and <hask>y</hask> have the same type.<br />
<br />
Sometimes it helps to divide a big function into smaller ones and give each of the small functions a signature.<br />
This also helps reading the program.<br />
<br />
If this does not help, too, then use a helper function.<br />
E.g. if you want to determine the size of an object a pointer points to,<br />
then you might define a function like<br />
<haskell><br />
sizeOfPtr :: Ptr a -> Int<br />
sizeOfPtr = sizeOf . (undefined :: Ptr a -> a)<br />
</haskell><br />
<!-- provided by Lennart Augustsson in http://www.haskell.org/pipermail/haskell-cafe/2010-January/072060.html --><br />
or<br />
<haskell><br />
sizeOfPtr :: Ptr a -> a -> Int<br />
sizeOfPtr _ a = sizeOf a<br />
<br />
sizeOf :: Ptr a -> Int<br />
sizeOf ptr = sizeOfPtr ptr undefined<br />
.<br />
</haskell><br />
<br />
== See also ==<br />
<br />
* Haskell-Cafe on [http://www.haskell.org/pipermail/haskell-cafe/2009-December/071064.html sizeOf on a type]<br />
* Haskell-Cafe on [http://www.haskell.org/pipermail/haskell-cafe/2008-June/044617.html What is a rigid type variable?]<br />
* Haskell-Cafe on [http://www.haskell.org/pipermail/haskell-cafe/2008-April/042174.html asserting the type of a binding in a "do" expression]<br />
<br />
[[Category:Glossary]]<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Scoped_type_variables&diff=61294Scoped type variables2016-11-14T00:49:31Z<p>Ryantm: </p>
<hr />
<div>Scoped Type Variables are an extension to Haskell's type system that allow free type variables to be re-used in the scope of a function.<br />
{{GHCUsersGuide|glasgow_exts|ghc-flag--XScopedTypeVariables|a Scoped Type Variables section]<br />
<br />
As an example, consider the following functions:<br />
<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables #-}<br />
<br />
...<br />
<br />
mkpair1 :: forall a b. a -> b -> (a,b)<br />
mkpair1 aa bb = (ida aa, bb)<br />
where<br />
ida :: a -> a -- This refers to a in the function's type signature<br />
ida = id<br />
<br />
mkpair2 :: forall a b. a -> b -> (a,b)<br />
mkpair2 aa bb = (ida aa, bb)<br />
where<br />
ida :: b -> b -- Illegal, because refers to b in type signature<br />
ida = id<br />
<br />
mkpair3 :: a -> b -> (a,b)<br />
mkpair3 aa bb = (ida aa, bb)<br />
where<br />
ida :: b -> b -- Legal, because b is now a free variable<br />
ida = id<br />
</haskell><br />
<br />
Scoped type variables make it possible to specify the particular type of a function in situations where it is not otherwise possible, which can in turn help avoid problems with the [[Monomorphism restriction]].<br />
<br />
This feature should be better documented in the Wiki, but this is a start.<br />
<br />
== Avoiding Scoped Type Variables ==<br />
<br />
Although Scoped Type Variables are often a simple solution, they are not available in all compilers.<br />
Often there is a solution that is Haskell 98.<br />
First, there is<br />
<haskell><br />
asTypeOf :: a -> a -> a<br />
asTypeOf a b = a<br />
.<br />
</haskell><br />
It is used like <hask>x `asTypeOf` y</hask> and has the same value like <hask>x</hask>,<br />
but type inference asserts that <hask>x</hask> and <hask>y</hask> have the same type.<br />
<br />
Sometimes it helps to divide a big function into smaller ones and give each of the small functions a signature.<br />
This also helps reading the program.<br />
<br />
If this does not help, too, then use a helper function.<br />
E.g. if you want to determine the size of an object a pointer points to,<br />
then you might define a function like<br />
<haskell><br />
sizeOfPtr :: Ptr a -> Int<br />
sizeOfPtr = sizeOf . (undefined :: Ptr a -> a)<br />
</haskell><br />
<!-- provided by Lennart Augustsson in http://www.haskell.org/pipermail/haskell-cafe/2010-January/072060.html --><br />
or<br />
<haskell><br />
sizeOfPtr :: Ptr a -> a -> Int<br />
sizeOfPtr _ a = sizeOf a<br />
<br />
sizeOf :: Ptr a -> Int<br />
sizeOf ptr = sizeOfPtr ptr undefined<br />
.<br />
</haskell><br />
<br />
== See also ==<br />
<br />
* Haskell-Cafe on [http://www.haskell.org/pipermail/haskell-cafe/2009-December/071064.html sizeOf on a type]<br />
* Haskell-Cafe on [http://www.haskell.org/pipermail/haskell-cafe/2008-June/044617.html What is a rigid type variable?]<br />
* Haskell-Cafe on [http://www.haskell.org/pipermail/haskell-cafe/2008-April/042174.html asserting the type of a binding in a "do" expression]<br />
<br />
[[Category:Glossary]]<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=61293GHC/Type families2016-11-14T00:48:14Z<p>Ryantm: </p>
<hr />
<div>{{GHCUsersGuide|glasgow_exts|type-families|a Type Family section}}<br />
<br />
<br />
Indexed type families, or '''type families''' for short, are a Haskell extension supporting ad-hoc overloading of data types. Type families are parametric types that can be assigned specialized representations based on the type parameters they are instantiated with. They are the data type analogue of [[Type class|type classes]]: families are used to define overloaded ''data'' in the same way that classes are used to define overloaded ''functions''. Type families are useful for generic programming, for creating highly parameterised library interfaces, and for creating interfaces with enhanced static information, much like dependent types.<br />
<br />
Type families come in two flavors: ''data families'' and ''type synonym families''. Data families are the indexed form of data and newtype definitions. Type synonym families are the indexed form of type synonyms. Each of these flavors can be defined in a standalone manner or ''associated'' with a type class. Standalone definitions are more general, while associated types can more clearly express how a type is used and lead to better error messages.<br />
<br />
''NB: see also Simon's [http://hackage.haskell.org/trac/ghc/blog/LetGeneralisationInGhc7 blog entry on let generalisation] for a significant change in the policy for let generalisation, driven by the type family extension. In brief: a few programs will puzzlingly fail to compile with <tt>-XTypeFamilies</tt> even though the code is legal Haskell 98.''<br />
<br />
== What are type families? ==<br />
<br />
The concept of a type family comes from type theory. An indexed type family in type theory is a partial function at the type level. Applying the function to parameters (called ''type indices'') yields a type. Type families permit a program to compute what data constructors it will operate on, rather than having them fixed statically (as with simple type systems) or treated as opaque unknowns (as with parametrically polymorphic types).<br />
<br />
Type families are to vanilla data types what type class methods are to regular functions. Vanilla polymorphic data types and functions have a single definition, which is used at all type instances. Classes and type families, on the other hand, have an interface definition and any number of instance definitions. A type family's interface definition declares its [[kind]] and its arity, or the number of type indices it takes. Instance definitions define the type family over some part of the domain.<br />
<br />
As a simple example of how type families differ from ordinary parametric data types, consider a strict list type. We can represent a list of <hask>Char</hask> in the usual way, with cons cells. We can do the same thing to represent a list of <hask>()</hask>, but since a strict <hask>()</hask> value carries no useful information, it would be more efficient to just store the length of the list. This can't be done with an ordinary parametric data type, because the data constructors used to represent the list would depend on the list's type parameter: if it's <hask>Char</hask> then the list consists of cons cells; if it's <hask>()</hask>, then the list consists of a single integer. We basically want to select between two different data types based on a type parameter. Using type families, this list type could be declared as follows:<br />
<br />
<haskell><br />
-- Declare a list-like data family<br />
data family XList a<br />
<br />
-- Declare a list-like instance for Char<br />
data instance XList Char = XCons !Char !(XList Char) | XNil<br />
<br />
-- Declare a number-like instance for ()<br />
data instance XList () = XListUnit !Int<br />
</haskell><br />
<br />
The right-hand sides of the two <code>data instance</code> declarations are exactly ordinary data definitions. In fact, a <code>data instance</code> declaration is nothing more than a shorthand for a <code>data</code> declaration followed by a <code>type instance</code> (see below) declaration. However, they define two instances of the same parametric data type, <hask>XList Char</hask> and <hask>XList ()</hask>, whereas ordinary data declarations define completely unrelated types. A recent [[Simonpj/Talk:FunWithTypeFuns|tutorial paper]] has more in-depth examples of programming with type families. <br />
<br />
[[GADT]]s bear some similarity to type families, in the sense that they allow a parametric type's constructors to depend on the type's parameters. However, all GADT constructors must be defined in one place, whereas type families can be extended. Functional dependencies are similar to type families, and many type classes that use functional dependencies can be equivalently expressed with type families. Type families provide a more functional style of type-level programming than the relational style of functional dependencies.<br />
<br />
== What do I need to use type families? ==<br />
<br />
Type families are a GHC extension enabled with the <code>-XTypeFamilies</code> flag or the <code>{-# LANGUAGE TypeFamilies #-}</code> pragma. The first stable release of GHC that properly supports type families is 6.10.1. (The 6.8 release included an early partial implementation, but its use is deprecated.) Please [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&group=priority&type=bug&order=id&desc=1 report bugs] via the GHC bug tracker, ideally accompanied by a small example program that demonstrates the problem. Use the [mailto:glasgow-haskell-users@haskell.org GHC mailing list] for questions or for a discussion of this language extension and its description on this wiki page.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.cs.ox.ac.uk/ralf.hinze/publications/GGTries.ps.gz generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
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-families.html#data-family-declarations ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analogous to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. 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.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.IntMap</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.IntMap.IntMap v)<br />
empty = GMapInt Data.IntMap.empty<br />
lookup k (GMapInt m) = Data.IntMap.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.IntMap.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before, any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundamental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Next, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right b) v (GMapEither gm1 gm2) = GMapEither gm1 (insert b v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.cs.ox.ac.uk/ralf.hinze/publications/index.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and querying a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the source code[http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs] for <hask>GMap</hask> from GHC's test suite.<br />
<br />
== Detailed definition of data families ==<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indices to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> keyword. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indices. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. In other words: '''the named type parameters of the data declaration must be a permutation of a subset of the class variables'''. <br />
<br />
Example is admissible:<br />
<haskell><br />
class C a b c where { data T c a :: * } -- OK<br />
class C a b c where { data T a a :: * } -- Bad: repeated variable<br />
class D a where { data T a x :: * } -- Bad: x is not a class variable<br />
class D a where { data T a :: * -> * } -- OK<br />
</haskell><br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed in type parameters, and type synonyms are allowed as long as they are fully applied and expand to a type that is itself admissible - exactly as this is required for occurrences of type synonyms in class instance parameters. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsense :: T a -> Int<br />
nonsense A = 1 -- WRONG: These two equations together...<br />
nonsense B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indices corresponding to class parameters must be identical to the type given in the instance head; here this is the first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instance declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Scoping of class parameters ====<br />
<br />
In the case of multi-parameter type classes, the visibility of class parameters in the right-hand side of associated family instances depends ''solely'' on the parameters of the data family. As an example, consider the simple class declaration<br />
<haskell><br />
class C a b where<br />
data T a<br />
</haskell><br />
Only one of the two class parameters is a parameter to the data family. Hence, the following instance declaration is invalid:<br />
<haskell><br />
instance C [c] d where<br />
data T [c] = MkT (c, d) -- WRONG!! 'd' is not in scope<br />
</haskell><br />
Here, the right-hand side of the data instance mentions the type variable <hask>d</hask> that does not occur in its left-hand side. We cannot admit such data instances as they would compromise type safety.<br />
<br />
==== Type class instances of family instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implicitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This is for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapEither</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
== An associated type synonym example ==<br />
<br />
Type synonym families are an alternative to functional dependencies, which makes functional dependency examples well suited to introduce type synonym families. In fact, type families are a more functional way to express the same as functional dependencies (despite the name!), as they replace the relational notation of functional dependencies by an expression-oriented notation; i.e., functions on types are really represented by functions and not relations.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from Mark Jones' seminal paper on functional dependencies:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
Instead of the multi-parameter type class, we use a single parameter class, and the parameter <hask>e</hask><br />
turned into an associated type synonym <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Instances change correspondingly. An instance of the two-parameter class<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
becomes an instance of a single-parameter class, where the dependent type parameter turns into an associated type instance declaration:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1, Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
== Detailed definition of type synonym families ==<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indices to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Parameters can also be given explicit kind signatures if needed. We call the number of parameters in a type family declaration, the family's arity, and all applications of a type family must be fully saturated w.r.t. to that arity. This requirement is unlike ordinary type synonyms and it implies that the kind of a type family is not sufficient to determine a family's arity, and hence in general, also insufficient to determine whether a type family application is well formed. As an example, consider the following declaration:<br />
<haskell><br />
type family F a b :: * -> * -- F's arity is 2, <br />
-- although its overall kind is * -> * -> * -> *<br />
</haskell><br />
Given this declaration the following are examples of well-formed and malformed types:<br />
<haskell><br />
F Char [Int] -- OK! Kind: * -> *<br />
F Char [Int] Bool -- OK! Kind: *<br />
F IO Bool -- WRONG: kind mismatch in the first argument<br />
F Bool -- WRONG: unsaturated application<br />
</haskell><br />
<br />
A top-level type family can be declared as open or closed. (Associated type<br />
families are always open.) A closed type family has all of its equations<br />
defined in one place and cannot be extended, whereas an open family can have<br />
instances spread across modules. The advantage of a closed family is that<br />
its equations are tried in order, similar to a term-level function definition:<br />
<haskell><br />
type family G a where<br />
G Int = Bool<br />
G a = Char<br />
</haskell><br />
With this definition, the type <hask>G Int</hask> becomes <hask>Bool</hask><br />
and, say, <hask>G Double</hask> becomes <hask>Char</hask>. See also [http://ghc.haskell.org/trac/ghc/wiki/NewAxioms here] for more information about closed type families.<br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
Exactly as in the case of an associated data declaration, '''the named type parameters must be a permutation of a subset of the class parameters'''. Examples<br />
<haskell><br />
class C a b c where { type T c a :: * } -- OK<br />
class D a where { type T a x :: * } -- No: x is not a class parameter<br />
class D a where { type T a :: * -> * } -- OK<br />
</haskell><br />
<br />
=== Type instance declarations ===<br />
<br />
Instance declarations of open type families are very similar to standard type synonym declarations. The only two differences are that the keyword <hask>type</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed, and type synonyms are allowed as long as they are fully applied and expand to a type that is admissible - these are the exact same requirements as for data instances. For example, the <hask>[e]</hask> instance for <hask>Elem</hask> is<br />
<haskell><br />
type instance Elem [e] = e<br />
</haskell><br />
<br />
A type family instance declaration must satisfy the following rules:<br />
* An appropriate family declaration is in scope - just like class instances require the class declaration to be visible. <br />
* The instance declaration conforms to the kind determined by its family declaration<br />
* The number of type parameters in an instance declaration matches the number of type parameters in the family declaration.<br />
* The right-hand side of a type instance must be a monotype (i.e., it may not include foralls) and after the expansion of all saturated vanilla type synonyms, no synonyms, except family synonyms may remain.<br />
<br />
Here are some examples of admissible and illegal type instances and closed families:<br />
<haskell><br />
type family F a :: *<br />
type instance F [Int] = Int -- OK!<br />
type instance F String = Char -- OK!<br />
type instance F (F a) = a -- WRONG: type parameter mentions a type family<br />
type instance F (forall a. (a, b)) = b -- WRONG: a forall type appears in a type parameter<br />
type instance F Float = forall a.a -- WRONG: right-hand side may not be a forall type<br />
<br />
type family F2 a where -- OK!<br />
F2 (Maybe Int) = Int<br />
F2 (Maybe Bool) = Bool<br />
F2 (Maybe a) = String<br />
<br />
type family G a b :: * -> *<br />
type instance G Int = (,) -- WRONG: must be two type parameters<br />
type instance G Int Char Float = Double -- WRONG: must be two type parameters<br />
</haskell><br />
<br />
==== Closed family simplification ====<br />
<br />
Included in ghc starting 7.8.1.<br />
<br />
When dealing with closed families, simplifying the type is harder than just finding a left-hand side that matches and replacing that with a right-hand side. GHC will select an equation to use in a given type family application (the "target") if and only if the following 2 conditions hold:<br />
<br />
# There is a substitution from the variables in the equation's LHS that makes the left-hand side of the branch coincide with the target.<br />
# For each previous equation in the family: either the LHS of that equation is ''apart'' from the type family application, '''or''' the equation is ''compatible'' with the chosen equation.<br />
<br />
Now, we define ''apart'' and ''compatible'':<br />
# Two types are ''apart'' when one cannot simplify to the other, even after arbitrary type-family simplifications<br />
# Two equations are ''compatible'' if, either, their LHSs are apart or their LHSs unify and their RHSs are the same under the substitution induced by the unification.<br />
<br />
Some examples are in order:<br />
<haskell><br />
type family F a where<br />
F Int = Bool<br />
F Bool = Char<br />
F a = Bool<br />
<br />
type family And (a :: Bool) (b :: Bool) :: Bool where<br />
And False c = False<br />
And True d = d<br />
And e False = False<br />
And f True = f<br />
And g g = g<br />
</haskell><br />
<br />
In <hask>F</hask>, all pairs of equations are compatible except the second and third. The first two are compatible because their LHSs are apart. The first and third are compatible because the unifying substitution leads the RHSs to be the same. But, the second and third are not compatible because neither of these conditions holds. As a result, GHC will not use the third equation to simplify a target unless that target is apart from <hask>Bool</hask>.<br />
<br />
In <hask>And</hask>, ''every'' pair of equations is compatible, meaning GHC never has to make the extra apartness check during simplification.<br />
<br />
Why do all of this? It's a matter of type safety. Consider this example:<br />
<br />
<haskell><br />
type family J a b where<br />
J a a = Int<br />
J a b = Bool<br />
</haskell><br />
<br />
Say GHC selected the second branch just because the first doesn't apply at the moment, because two type variables are distinct. The problem is that those variables might later be instantiated at the same value, and then the first branch would have applied. You can convince this sort of inconsistency to produce <hask>unsafeCoerce</hask>.<br />
<br />
It gets worse. GHC has no internal notion of inequality, so it can't use previous, failed term-level GADT pattern matches to refine its type assumptions. For example:<br />
<br />
<haskell><br />
data G :: * -> * where<br />
GInt :: G Int<br />
GBool :: G Bool<br />
<br />
type family Foo (a :: *) :: * where<br />
Foo Int = Char<br />
Foo a = Double<br />
<br />
bar :: G a -> Foo a<br />
bar GInt = 'x'<br />
bar _ = 3.14<br />
</haskell><br />
<br />
The last line will fail to typecheck, because GHC doesn't know that the type variable <hask>a</hask> can't be <hask>Int</hask> here, even though it's obvious. The only general way to fix this is to have inequality evidence introduced into GHC, and that's a big deal and we don't know if we have the motivation for such a change yet.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>[e]</hask> instance for <hask>Elem</hask> becomes:<br />
<haskell><br />
instance (Eq (Elem [e])) => Collects ([e]) where<br />
type Elem [e] = e<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is <hask>[e]</hask>, which coincides with the only class parameter.<br />
<br />
Instances for an associated family can only appear as part of instance declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of an open type family used in a single program must be compatible, in the form defined above. This condition is independent of whether the type family is associated or not, and it is not only a matter of consistency, but one of type safety. <br />
<br />
Here are two examples to illustrate the condition under which overlap is permitted.<br />
<haskell><br />
type instance F (a, Int) = [a]<br />
type instance F (Int, b) = [b] -- overlap permitted<br />
<br />
type instance G (a, Int) = [a]<br />
type instance G (Char, a) = [a] -- ILLEGAL overlap, as [Char] /= [Int]<br />
</haskell><br />
<br />
==== Decidability ====<br />
<br />
In order to guarantee that type inference in the presence of type families is decidable, we need to place a number of additional restrictions on the formation of type instance declarations (c.f., Definition 5 (Relaxed Conditions) of [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking with Open Type Functions]). Instance declarations have the general form<br />
<haskell><br />
type instance F t1 .. tn = t<br />
</haskell><br />
where we require that for every type family application <hask>(G s1 .. sm)</hask> in <hask>t</hask>, <br />
# <hask>s1 .. sm</hask> do not contain any type family constructors,<br />
# the total number of symbols (data type constructors and type variables) in <hask>s1 .. sm</hask> is strictly smaller than in <hask>t1 .. tn</hask>, and<br />
# for every type variable <hask>a</hask>, <hask>a</hask> occurs in <hask>s1 .. sm</hask> at most as often as in <hask>t1 .. tn</hask>.<br />
These restrictions are easily verified and ensure termination of type inference. However, they are not sufficient to guarantee completeness of type inference in the presence of, so called, ''loopy equalities'', such as <hask>a ~ [F a]</hask>, where a recursive occurrence of a type variable is underneath a family application and data constructor application - see the above mentioned paper for details. <br />
<br />
If the option <tt>-XUndecidableInstances</tt> is passed to the compiler, the above restrictions are not enforced and it is on the programmer to ensure termination of the normalisation of type families during type inference.<br />
<br />
=== Equality constraints ===<br />
<br />
Type context can include equality constraints of the form <hask>t1 ~ t2</hask>, which denote that the types <hask>t1</hask> and <hask>t2</hask> need to be the same. In the presence of type families, whether two types are equal cannot generally be decided locally. Hence, the contexts of function signatures may include equality constraints, as in the following example:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
</haskell><br />
where we require that the element type of <hask>c1</hask> and <hask>c2</hask> are the same. In general, the types <hask>t1</hask> and <hask>t2</hask> of an equality constraint may be arbitrary monotypes; i.e., they may not contain any quantifiers, independent of whether higher-rank types are otherwise enabled.<br />
<br />
Equality constraints can also appear in class and instance contexts. The former enable a simple translation of programs using functional dependencies into programs using family synonyms instead. The general idea is to rewrite a class declaration of the form<br />
<haskell><br />
class C a b | a -> b<br />
</haskell><br />
to<br />
<haskell><br />
class (F a ~ b) => C a b where<br />
type F a<br />
</haskell><br />
That is, we represent every functional dependency (FD) <hask>a1 .. an -> b</hask> by an FD type family <hask>F a1 .. an</hask> and a superclass context equality <hask>F a1 .. an ~ b</hask>, essentially giving a name to the functional dependency. In class instances, we define the type instances of FD families in accordance with the class head. Method signatures are not affected by that process.<br />
<br />
== Frequently asked questions ==<br />
<br />
=== Comparing type families and functional dependencies ===<br />
<br />
Functional dependencies cover some of the same territory as type families. How do the two compare?<br />
There are some articles about this question:<br />
<br />
* Experiences in converting functional dependencies to type families: "[[Functional dependencies vs. type families]]"<br />
* [http://hackage.haskell.org/trac/ghc/wiki/TFvsFD GHC trac] on a comparison of functional dependencies and type families<br />
<br />
=== Injectivity, type inference, and ambiguity ===<br />
<br />
A common problem is this<br />
<haskell><br />
type family F a<br />
<br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g :: F Int -> F Int<br />
g x = f x<br />
</haskell><br />
The compiler complains about the definition of <tt>g</tt> saying<br />
<code><br />
Couldn't match expected type `F Int' against inferred type `F a1'<br />
</code><br />
In type-checking <tt>g</tt>'s right hand side GHC discovers (by instantiating <tt>f</tt>'s type with a fresh type variable) that it has type <tt>F a1 -> F a1</tt> for some as-yet-unknown type <tt>a1</tt>. Now it tries to make the inferred type match <tt>g</tt>'s type signature. Well, you say, just make <tt>a1</tt> equal to <tt>Int</tt> and you are done. True, but what if there were these instances<br />
<haskell><br />
type instance F Int = Bool<br />
type instance F Char = Bool<br />
</haskell><br />
Then making <tt>a1</tt> equal to <tt>Char</tt> would ''also'' make the two types equal. Because there is (potentially) more than one choice, the program is rejected.<br />
<br />
However (and confusingly) if you omit the type signature on <tt>g</tt> altogether, thus<br />
<haskell><br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g x = f x<br />
</haskell><br />
GHC will happily infer the type <tt>g :: F a -> F a</tt>. But you can't ''write'' that type signature or, indeed, the more specific one above. (Arguably this behaviour, where GHC ''infers'' a type it can't ''check'', is very confusing. I suppose we could make GHC reject both programs, with and without type signatures.)<br />
<br />
'''What is the problem?''' The nub of the issue is this: knowing that <tt>F t1</tt>=<tt>F t2</tt> does ''not'' imply that <tt>t1</tt> = <tt>t2</tt>.<br />
The difficulty is that the type function <tt>F</tt> need not be ''injective''; it can map two distinct types to the same type. For an injective type constructor like <tt>Maybe</tt>, if we know that <tt>Maybe t1</tt> = <tt>Maybe t2</tt>, then we know that <tt>t1</tt> = <tt>t2</tt>. But not so for non-injective type functions.<br />
<br />
The problem starts with <tt>f</tt>. Its type is ''ambiguous''; even if I know the argument and result types for <tt>f</tt>, I cannot use that to find the type at which <tt>a</tt> should be instantiated. (So arguably, <tt>f</tt> should be rejected as having an ambiguous type, and probably will be in future.) The situation is well known in type classes: <br />
<haskell><br />
bad :: (Read a, Show a) => String -> String<br />
bad x = show (read x)<br />
</haskell><br />
At a call of <tt>bad</tt> one cannot tell at what type <tt>a</tt> should be instantiated.<br />
<br />
The only solution is to avoid ambiguous types. In the type signature of a function, <br />
* Ensure that every type variable occurs in the part after the "<tt>=></tt>"<br />
* Ensure that every type variable appears at least once outside a type function call.<br />
Alternatively, you can use data families, which create new types and are therefore injective. The following code works:<br />
<br />
<haskell>data family F a<br />
<br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g :: F Int -> F Int<br />
g x = f x</haskell><br />
<br />
== References ==<br />
<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html Associated Types with Class.] Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, and Simon Marlow. In ''Proceedings of The 32nd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL'05)'', pages 1-13, ACM Press, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms.] Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In ''Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 241-253, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SCPD07.html System F with Type Equality Coercions.] Martin Sulzmann, Manuel M. T. Chakravarty, Simon Peyton Jones, and Kevin Donnelly. In ''Proceedings of The Third ACM SIGPLAN Workshop on Types in Language Design and Implementation'', ACM Press, 2007.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking With Open Type Functions.] Tom Schrijvers, Simon Peyton-Jones, Manuel M. T. Chakravarty, Martin Sulzmann. In ''Proceedings of The 13th ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 51-62, 2008.<br />
* [[Simonpj/Talk:FunWithTypeFuns | Fun with Type Functions]] Oleg Kiselyov, Simon Peyton Jones, Chung-chieh Shan (the source for this paper can be found at http://patch-tag.com/r/schoenfinkel/typefunctions/wiki ) <br />
<br />
[[Category:Type-level programming]]<br />
[[Category:Language extensions]]<br />
[[Category:GHC|Indexed types]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=GHC/Type_families&diff=61292GHC/Type families2016-11-14T00:46:24Z<p>Ryantm: </p>
<hr />
<div>{{{GHCUsersGuide|glasgow_exts|type-families|a Type Family section}}}<br />
<br />
<br />
Indexed type families, or '''type families''' for short, are a Haskell extension supporting ad-hoc overloading of data types. Type families are parametric types that can be assigned specialized representations based on the type parameters they are instantiated with. They are the data type analogue of [[Type class|type classes]]: families are used to define overloaded ''data'' in the same way that classes are used to define overloaded ''functions''. Type families are useful for generic programming, for creating highly parameterised library interfaces, and for creating interfaces with enhanced static information, much like dependent types.<br />
<br />
Type families come in two flavors: ''data families'' and ''type synonym families''. Data families are the indexed form of data and newtype definitions. Type synonym families are the indexed form of type synonyms. Each of these flavors can be defined in a standalone manner or ''associated'' with a type class. Standalone definitions are more general, while associated types can more clearly express how a type is used and lead to better error messages.<br />
<br />
''NB: see also Simon's [http://hackage.haskell.org/trac/ghc/blog/LetGeneralisationInGhc7 blog entry on let generalisation] for a significant change in the policy for let generalisation, driven by the type family extension. In brief: a few programs will puzzlingly fail to compile with <tt>-XTypeFamilies</tt> even though the code is legal Haskell 98.''<br />
<br />
== What are type families? ==<br />
<br />
The concept of a type family comes from type theory. An indexed type family in type theory is a partial function at the type level. Applying the function to parameters (called ''type indices'') yields a type. Type families permit a program to compute what data constructors it will operate on, rather than having them fixed statically (as with simple type systems) or treated as opaque unknowns (as with parametrically polymorphic types).<br />
<br />
Type families are to vanilla data types what type class methods are to regular functions. Vanilla polymorphic data types and functions have a single definition, which is used at all type instances. Classes and type families, on the other hand, have an interface definition and any number of instance definitions. A type family's interface definition declares its [[kind]] and its arity, or the number of type indices it takes. Instance definitions define the type family over some part of the domain.<br />
<br />
As a simple example of how type families differ from ordinary parametric data types, consider a strict list type. We can represent a list of <hask>Char</hask> in the usual way, with cons cells. We can do the same thing to represent a list of <hask>()</hask>, but since a strict <hask>()</hask> value carries no useful information, it would be more efficient to just store the length of the list. This can't be done with an ordinary parametric data type, because the data constructors used to represent the list would depend on the list's type parameter: if it's <hask>Char</hask> then the list consists of cons cells; if it's <hask>()</hask>, then the list consists of a single integer. We basically want to select between two different data types based on a type parameter. Using type families, this list type could be declared as follows:<br />
<br />
<haskell><br />
-- Declare a list-like data family<br />
data family XList a<br />
<br />
-- Declare a list-like instance for Char<br />
data instance XList Char = XCons !Char !(XList Char) | XNil<br />
<br />
-- Declare a number-like instance for ()<br />
data instance XList () = XListUnit !Int<br />
</haskell><br />
<br />
The right-hand sides of the two <code>data instance</code> declarations are exactly ordinary data definitions. In fact, a <code>data instance</code> declaration is nothing more than a shorthand for a <code>data</code> declaration followed by a <code>type instance</code> (see below) declaration. However, they define two instances of the same parametric data type, <hask>XList Char</hask> and <hask>XList ()</hask>, whereas ordinary data declarations define completely unrelated types. A recent [[Simonpj/Talk:FunWithTypeFuns|tutorial paper]] has more in-depth examples of programming with type families. <br />
<br />
[[GADT]]s bear some similarity to type families, in the sense that they allow a parametric type's constructors to depend on the type's parameters. However, all GADT constructors must be defined in one place, whereas type families can be extended. Functional dependencies are similar to type families, and many type classes that use functional dependencies can be equivalently expressed with type families. Type families provide a more functional style of type-level programming than the relational style of functional dependencies.<br />
<br />
== What do I need to use type families? ==<br />
<br />
Type families are a GHC extension enabled with the <code>-XTypeFamilies</code> flag or the <code>{-# LANGUAGE TypeFamilies #-}</code> pragma. The first stable release of GHC that properly supports type families is 6.10.1. (The 6.8 release included an early partial implementation, but its use is deprecated.) Please [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&group=priority&type=bug&order=id&desc=1 report bugs] via the GHC bug tracker, ideally accompanied by a small example program that demonstrates the problem. Use the [mailto:glasgow-haskell-users@haskell.org GHC mailing list] for questions or for a discussion of this language extension and its description on this wiki page.<br />
<br />
== An associated data type example ==<br />
<br />
As an example, consider Ralf Hinze's [http://www.cs.ox.ac.uk/ralf.hinze/publications/GGTries.ps.gz generalised tries], a form of generic finite maps. <br />
<br />
=== The class declaration ===<br />
<br />
We define a type class whose instances are the types that we can use as keys in our generic maps:<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
empty :: GMap k v<br />
lookup :: k -> GMap k v -> Maybe v<br />
insert :: k -> v -> GMap k v -> GMap k v<br />
</haskell><br />
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-families.html#data-family-declarations ''kind signature''] (here <hask>* -> *</hask>) for the associated data type <hask>GMap k</hask> - analogous to how methods receive a type signature in a class declaration.<br />
<br />
What it is important to notice is that the first parameter of the associated type <hask>GMap</hask> coincides with the class parameter of <hask>GMapKey</hask>. 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.<br />
<br />
The second important point is that as <hask>GMap k</hask> has kind <hask>* -> *</hask> and <hask>k</hask> (implicitly) has kind <hask>*</hask>, the type constructor <hask>GMap</hask> (without an argument) has kind <hask>* -> * -> *</hask>. Consequently, we see that <hask>GMap</hask> is applied to two arguments in the signatures of the methods <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>.<br />
<br />
=== An Int instance ===<br />
<br />
To use Ints as keys into generic maps, we declare an instance that simply uses <hask>Data.IntMap</hask>, thusly:<br />
<haskell><br />
instance GMapKey Int where<br />
data GMap Int v = GMapInt (Data.IntMap.IntMap v)<br />
empty = GMapInt Data.IntMap.empty<br />
lookup k (GMapInt m) = Data.IntMap.lookup k m<br />
insert k v (GMapInt m) = GMapInt (Data.IntMap.insert k v m)<br />
</haskell><br />
The <hask>Int</hask> instance of the associated data type <hask>GMap</hask> needs to have both of its parameters, but as only the first one corresponds to a class parameter, the second needs to be a type variable (here <hask>v</hask>). As mentioned before, any associated type parameter that corresponds to a class parameter must be identical to the class parameter in each instance. The right hand side of the associated data declaration is like that of any other data type.<br />
<br />
NB: At the moment, GADT syntax is not allowed for associated data types (or other indexed types). This is not a fundamental limitation, but just a shortcoming of the current implementation, which we expect to lift in the future.<br />
<br />
As an exercise, implement an instance for <hask>Char</hask> that maps back to the <hask>Int</hask> instance using the conversion functions <hask>Char.ord</hask> and <hask>Char.chr</hask>.<br />
<br />
=== A unit instance ===<br />
<br />
Generic definitions, apart from elementary types, typically cover units, products, and sums. We start here with the unit instance for <hask>GMap</hask>:<br />
<haskell><br />
instance GMapKey () where<br />
data GMap () v = GMapUnit (Maybe v)<br />
empty = GMapUnit Nothing<br />
lookup () (GMapUnit v) = v<br />
insert () v (GMapUnit _) = GMapUnit $ Just v<br />
</haskell><br />
For unit, the map is just a <hask>Maybe</hask> value.<br />
<br />
=== Product and sum instances ===<br />
<br />
Next, let us define the instances for pairs and sums (i.e., <hask>Either</hask>):<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (a, b) where<br />
data GMap (a, b) v = GMapPair (GMap a (GMap b v))<br />
empty = GMapPair empty<br />
lookup (a, b) (GMapPair gm) = lookup a gm >>= lookup b <br />
insert (a, b) v (GMapPair gm) = GMapPair $ case lookup a gm of<br />
Nothing -> insert a (insert b v empty) gm<br />
Just gm2 -> insert a (insert b v gm2 ) gm<br />
<br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
empty = GMapEither empty empty<br />
lookup (Left a) (GMapEither gm1 _gm2) = lookup a gm1<br />
lookup (Right b) (GMapEither _gm1 gm2 ) = lookup b gm2<br />
insert (Left a) v (GMapEither gm1 gm2) = GMapEither (insert a v gm1) gm2<br />
insert (Right b) v (GMapEither gm1 gm2) = GMapEither gm1 (insert b v gm2)<br />
</haskell><br />
If you find this code algorithmically surprising, I'd suggest to have a look at [http://www.cs.ox.ac.uk/ralf.hinze/publications/index.html#J4 Ralf Hinze's paper]. The only novelty concerning associated types, in these two instances, is that the instances have a context <hask>(GMapKey a, GMapKey b)</hask>. Consequently, the right hand sides of the associated type declarations can use <hask>GMap</hask> recursively at the key types <hask>a</hask> and <hask>b</hask> - not unlike the method definitions use the class methods recursively at the types for which the class is given in the instance context.<br />
<br />
=== Using a generic map ===<br />
<br />
Finally, some code building and querying a generic map:<br />
<haskell><br />
myGMap :: GMap (Int, Either Char ()) String<br />
myGMap = insert (5, Left 'c') "(5, Left 'c')" $<br />
insert (4, Right ()) "(4, Right ())" $<br />
insert (5, Right ()) "This is the one!" $<br />
insert (5, Right ()) "This is the two!" $<br />
insert (6, Right ()) "(6, Right ())" $<br />
insert (5, Left 'a') "(5, Left 'a')" $<br />
empty<br />
main = putStrLn $ maybe "Couldn't find key!" id $ lookup (5, Right ()) myGMap<br />
</haskell><br />
<br />
=== Download the code ===<br />
<br />
If you want to play with this example without copying it off the wiki, just download the source code[http://darcs.haskell.org/testsuite/tests/ghc-regress/indexed-types/should_run/GMapAssoc.hs] for <hask>GMap</hask> from GHC's test suite.<br />
<br />
== Detailed definition of data families ==<br />
<br />
Data families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated types). The former is the more general variant, as it lacks the requirement for the type-indices to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed data families are introduced by a signature, such as <br />
<haskell><br />
data family GMap k :: * -> *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard data declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
data family Array e<br />
</haskell><br />
Named arguments can also be given explicit kind signatures if needed. Just as with [http://www.haskell.org/ghc/docs/latest/html/users_guide/gadt.html GADT declarations] named arguments are entirely optional, so that we can declare <hask>Array</hask> alternatively with<br />
<haskell><br />
data family Array :: * -> *<br />
</haskell><br />
<br />
==== Associated family declarations ====<br />
<br />
When a data family is declared as part of a type class, we drop the <hask>family</hask> keyword. The <hask>GMap</hask> declaration takes the following form<br />
<haskell><br />
class GMapKey k where<br />
data GMap k :: * -> *<br />
...<br />
</haskell><br />
In contrast to toplevel declarations, named arguments must be used for all type parameters that are to be used as type-indices. Moreover, the argument names must be class parameters. Each class parameter may only be used at most once per associated type, but some may be omitted and they may be in an order other than in the class head. In other words: '''the named type parameters of the data declaration must be a permutation of a subset of the class variables'''. <br />
<br />
Example is admissible:<br />
<haskell><br />
class C a b c where { data T c a :: * } -- OK<br />
class C a b c where { data T a a :: * } -- Bad: repeated variable<br />
class D a where { data T a x :: * } -- Bad: x is not a class variable<br />
class D a where { data T a :: * -> * } -- OK<br />
</haskell><br />
<br />
=== Instance declarations ===<br />
<br />
Instance declarations of data and newtype families are very similar to standard data and newtype declarations. The only two differences are that the keyword <hask>data</hask> or <hask>newtype</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed in type parameters, and type synonyms are allowed as long as they are fully applied and expand to a type that is itself admissible - exactly as this is required for occurrences of type synonyms in class instance parameters. For example, the <hask>Either</hask> instance for <hask>GMap</hask> is<br />
<haskell><br />
data instance GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
</haskell><br />
In this example, the declaration has only one variant. In general, it can be any number.<br />
<br />
Data and newtype instance declarations are only legit when an appropriate family declaration is in scope - just like class instances require the class declaration to be visible. Moreover, each instance declaration has to conform to the kind determined by its family declaration. This implies that the number of parameters of an instance declaration matches the arity determined by the kind of the family. Although all data families are declared with the <hask>data</hask> keyword, instances can be either <hask>data</hask> or <hask>newtype</hask>s, or a mix of both.<br />
<br />
Even if type families are defined as toplevel declarations, functions that perform different computations for different family instances still need to be defined as methods of type classes. In particular, the following is not possible:<br />
<haskell><br />
data family T a<br />
data instance T Int = A<br />
data instance T Char = B<br />
nonsense :: T a -> Int<br />
nonsense A = 1 -- WRONG: These two equations together...<br />
nonsense B = 2 -- ...will produce a type error.<br />
</haskell><br />
Given the functionality provided by GADTs (Generalised Algebraic Data Types), it might seem as if a definition, such as the above, should be feasible. However, type families - in contrast to GADTs - are ''open''; i.e., new instances can always be added, possibly in other modules. Supporting pattern matching across different data instances would require a form of extensible case construct.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>Either</hask> instance for <hask>GMap</hask> becomes:<br />
<haskell><br />
instance (GMapKey a, GMapKey b) => GMapKey (Either a b) where<br />
data GMap (Either a b) v = GMapEither (GMap a v) (GMap b v)<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indices corresponding to class parameters must be identical to the type given in the instance head; here this is the first argument of <hask>GMap</hask>, namely <hask>Either a b</hask>, which coincides with the only class parameter. Any parameters to the family constructor that do not correspond to class parameters, need to be variables in every instance; here this is the variable <hask>v</hask>.<br />
<br />
Instances for an associated family can only appear as part of instance declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Scoping of class parameters ====<br />
<br />
In the case of multi-parameter type classes, the visibility of class parameters in the right-hand side of associated family instances depends ''solely'' on the parameters of the data family. As an example, consider the simple class declaration<br />
<haskell><br />
class C a b where<br />
data T a<br />
</haskell><br />
Only one of the two class parameters is a parameter to the data family. Hence, the following instance declaration is invalid:<br />
<haskell><br />
instance C [c] d where<br />
data T [c] = MkT (c, d) -- WRONG!! 'd' is not in scope<br />
</haskell><br />
Here, the right-hand side of the data instance mentions the type variable <hask>d</hask> that does not occur in its left-hand side. We cannot admit such data instances as they would compromise type safety.<br />
<br />
==== Type class instances of family instances ====<br />
<br />
Type class instances of instances of data families can be defined as usual, and in particular data instance declarations can have <hask>deriving</hask> clauses. For example, we can write<br />
<haskell><br />
data GMap () v = GMapUnit (Maybe v)<br />
deriving Show<br />
</haskell><br />
which implicitly defines an instance of the form<br />
<haskell><br />
instance Show v => Show (GMap () v) where ...<br />
</haskell><br />
<br />
Note that class instances are always for particular ''instances'' of a data family and never for an entire family as a whole. This is for essentially the same reasons that we cannot define a toplevel function that performs pattern matching on the data constructors of ''different'' instances of a single type family. It would require a form of extensible case construct.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of a data family used in a single program may not overlap at all, independent of whether they are associated or not. In contrast to type class instances, this is not only a matter of consistency, but one of type safety.<br />
<br />
=== Import and export ===<br />
<br />
The association of data constructors with type families is more dynamic than that is the case with standard data and newtype declarations. In the standard case, the notation <hask>T(..)</hask> in an import or export list denotes the type constructor and all the data constructors introduced in its declaration. However, a family declaration never introduces any data constructors; instead, data constructors are introduced by family instances. As a result, which data constructors are associated with a type family depends on the currently visible instance declarations for that family. Consequently, an import or export item of the form <hask>T(..)</hask> denotes the family constructor and all currently visible data constructors - in the case of an export item, these may be either imported or defined in the current module. The treatment of import and export items that explicitly list data constructors, such as <hask>GMap(GMapEither)</hask>, is analogous.<br />
<br />
==== Associated families ====<br />
<br />
As expected, an import or export item of the form <hask>C(..)</hask> denotes all of the class' methods and associated types. However, when associated types are explicitly listed as subitems of a class, we need some new syntax, as uppercase identifiers as subitems are usually data constructors, not type constructors. To clarify that we denote types here, each associated type name needs to be prefixed by the keyword <hask>type</hask>. So for example, when explicitly listing the components of the <hask>GMapKey</hask> class, we write <hask>GMapKey(type GMap, empty, lookup, insert)</hask>.<br />
<br />
==== Examples ====<br />
<br />
Assuming our running <hask>GMapKey</hask> class example, let us look at some export lists and their meaning:<br />
<br />
* <hask>module GMap (GMapKey) where...</hask>: Exports just the class name.<br />
* <hask>module GMap (GMapKey(..)) where...</hask>: Exports the class, the associated type <hask>GMap</hask> and the member functions <hask>empty</hask>, <hask>lookup</hask>, and <hask>insert</hask>. None of the data constructors is exported.<br />
* <hask>module GMap (GMapKey(..), GMap(..)) where...</hask>: As before, but also exports all the data constructors <hask>GMapInt</hask>, <hask>GMapChar</hask>, <hask>GMapUnit</hask>, <hask>GMapPair</hask>, and <hask>GMapEither</hask>.<br />
* <hask>module GMap (GMapKey(empty, lookup, insert), GMap(..)) where...</hask>: As before.<br />
* <hask>module GMap (GMapKey, empty, lookup, insert, GMap(..)) where...</hask>: As before.<br />
<br />
Finally, you can write <hask>GMapKey(type GMap)</hask> to denote both the class <hask>GMapKey</hask> as well as its associated type <hask>GMap</hask>. However, you cannot write <hask>GMapKey(type GMap(..))</hask> &mdash; i.e., sub-component specifications cannot be nested. To specify <hask>GMap</hask>'s data constructors, you have to list it separately.<br />
<br />
==== Instances ====<br />
<br />
Family instances are implicitly exported, just like class instances. However, this applies only to the heads of instances, not to the data constructors an instance defines.<br />
<br />
== An associated type synonym example ==<br />
<br />
Type synonym families are an alternative to functional dependencies, which makes functional dependency examples well suited to introduce type synonym families. In fact, type families are a more functional way to express the same as functional dependencies (despite the name!), as they replace the relational notation of functional dependencies by an expression-oriented notation; i.e., functions on types are really represented by functions and not relations.<br />
<br />
=== The <hask>class</hask> declaration ===<br />
<br />
Here's an example from Mark Jones' seminal paper on functional dependencies:<br />
<haskell><br />
class Collects e ce | ce -> e where<br />
empty :: ce<br />
insert :: e -> ce -> ce<br />
member :: e -> ce -> Bool<br />
toList :: ce -> [e]<br />
</haskell><br />
<br />
With associated type synonyms we can write this as<br />
<haskell><br />
class Collects ce where<br />
type Elem ce<br />
empty :: ce<br />
insert :: Elem ce -> ce -> ce<br />
member :: Elem ce -> ce -> Bool<br />
toList :: ce -> [Elem ce]<br />
</haskell><br />
Instead of the multi-parameter type class, we use a single parameter class, and the parameter <hask>e</hask><br />
turned into an associated type synonym <hask>Elem ce</hask>.<br />
<br />
=== An <hask>instance</hask>===<br />
<br />
Instances change correspondingly. An instance of the two-parameter class<br />
<haskell><br />
instance Eq e => Collects e [e] where<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
becomes an instance of a single-parameter class, where the dependent type parameter turns into an associated type instance declaration:<br />
<haskell><br />
instance Eq e => Collects [e] where<br />
type Elem [e] = e<br />
empty = []<br />
insert e l = (e:l)<br />
member e [] = False<br />
member e (x:xs) <br />
| e == x = True<br />
| otherwise = member e xs<br />
toList l = l<br />
</haskell><br />
<br />
=== Using generic collections ===<br />
<br />
With Functional Dependencies the code would be:<br />
<haskell><br />
sumCollects :: (Collects e c1, Collects e c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
In contrast, with associated type synonyms, we get:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
sumCollects c1 c2 = foldr insert c2 (toList c1)<br />
</haskell><br />
<br />
== Detailed definition of type synonym families ==<br />
<br />
Type families appear in two flavours: (1) they can be defined on the toplevel or (2) they can appear inside type classes (in which case they are known as associated type synonyms). The former is the more general variant, as it lacks the requirement for the type-indices to coincide with the class parameters. However, the latter can lead to more clearly structured code and compiler warnings if some type instances were - possibly accidentally - omitted. In the following, we always discuss the general toplevel form first and then cover the additional constraints placed on associated types.<br />
<br />
=== Family declarations ===<br />
<br />
Indexed type families are introduced by a signature, such as <br />
<haskell><br />
type family Elem c :: *<br />
</haskell><br />
The special <hask>family</hask> distinguishes family from standard type declarations. The result kind annotation is optional and, as usual, defaults to <hask>*</hask> if omitted. An example is<br />
<haskell><br />
type family Elem c<br />
</haskell><br />
Parameters can also be given explicit kind signatures if needed. We call the number of parameters in a type family declaration, the family's arity, and all applications of a type family must be fully saturated w.r.t. to that arity. This requirement is unlike ordinary type synonyms and it implies that the kind of a type family is not sufficient to determine a family's arity, and hence in general, also insufficient to determine whether a type family application is well formed. As an example, consider the following declaration:<br />
<haskell><br />
type family F a b :: * -> * -- F's arity is 2, <br />
-- although its overall kind is * -> * -> * -> *<br />
</haskell><br />
Given this declaration the following are examples of well-formed and malformed types:<br />
<haskell><br />
F Char [Int] -- OK! Kind: * -> *<br />
F Char [Int] Bool -- OK! Kind: *<br />
F IO Bool -- WRONG: kind mismatch in the first argument<br />
F Bool -- WRONG: unsaturated application<br />
</haskell><br />
<br />
A top-level type family can be declared as open or closed. (Associated type<br />
families are always open.) A closed type family has all of its equations<br />
defined in one place and cannot be extended, whereas an open family can have<br />
instances spread across modules. The advantage of a closed family is that<br />
its equations are tried in order, similar to a term-level function definition:<br />
<haskell><br />
type family G a where<br />
G Int = Bool<br />
G a = Char<br />
</haskell><br />
With this definition, the type <hask>G Int</hask> becomes <hask>Bool</hask><br />
and, say, <hask>G Double</hask> becomes <hask>Char</hask>. See also [http://ghc.haskell.org/trac/ghc/wiki/NewAxioms here] for more information about closed type families.<br />
<br />
==== Associated family declarations ====<br />
<br />
When a type family is declared as part of a type class, we drop the <hask>family</hask> special. The <hask>Elem</hask> declaration takes the following form<br />
<haskell><br />
class Collects ce where<br />
type Elem ce :: *<br />
...<br />
</haskell><br />
Exactly as in the case of an associated data declaration, '''the named type parameters must be a permutation of a subset of the class parameters'''. Examples<br />
<haskell><br />
class C a b c where { type T c a :: * } -- OK<br />
class D a where { type T a x :: * } -- No: x is not a class parameter<br />
class D a where { type T a :: * -> * } -- OK<br />
</haskell><br />
<br />
=== Type instance declarations ===<br />
<br />
Instance declarations of open type families are very similar to standard type synonym declarations. The only two differences are that the keyword <hask>type</hask> is followed by <hask>instance</hask> and that some or all of the type arguments can be non-variable types, but may not contain forall types or type synonym families. However, data families are generally allowed, and type synonyms are allowed as long as they are fully applied and expand to a type that is admissible - these are the exact same requirements as for data instances. For example, the <hask>[e]</hask> instance for <hask>Elem</hask> is<br />
<haskell><br />
type instance Elem [e] = e<br />
</haskell><br />
<br />
A type family instance declaration must satisfy the following rules:<br />
* An appropriate family declaration is in scope - just like class instances require the class declaration to be visible. <br />
* The instance declaration conforms to the kind determined by its family declaration<br />
* The number of type parameters in an instance declaration matches the number of type parameters in the family declaration.<br />
* The right-hand side of a type instance must be a monotype (i.e., it may not include foralls) and after the expansion of all saturated vanilla type synonyms, no synonyms, except family synonyms may remain.<br />
<br />
Here are some examples of admissible and illegal type instances and closed families:<br />
<haskell><br />
type family F a :: *<br />
type instance F [Int] = Int -- OK!<br />
type instance F String = Char -- OK!<br />
type instance F (F a) = a -- WRONG: type parameter mentions a type family<br />
type instance F (forall a. (a, b)) = b -- WRONG: a forall type appears in a type parameter<br />
type instance F Float = forall a.a -- WRONG: right-hand side may not be a forall type<br />
<br />
type family F2 a where -- OK!<br />
F2 (Maybe Int) = Int<br />
F2 (Maybe Bool) = Bool<br />
F2 (Maybe a) = String<br />
<br />
type family G a b :: * -> *<br />
type instance G Int = (,) -- WRONG: must be two type parameters<br />
type instance G Int Char Float = Double -- WRONG: must be two type parameters<br />
</haskell><br />
<br />
==== Closed family simplification ====<br />
<br />
Included in ghc starting 7.8.1.<br />
<br />
When dealing with closed families, simplifying the type is harder than just finding a left-hand side that matches and replacing that with a right-hand side. GHC will select an equation to use in a given type family application (the "target") if and only if the following 2 conditions hold:<br />
<br />
# There is a substitution from the variables in the equation's LHS that makes the left-hand side of the branch coincide with the target.<br />
# For each previous equation in the family: either the LHS of that equation is ''apart'' from the type family application, '''or''' the equation is ''compatible'' with the chosen equation.<br />
<br />
Now, we define ''apart'' and ''compatible'':<br />
# Two types are ''apart'' when one cannot simplify to the other, even after arbitrary type-family simplifications<br />
# Two equations are ''compatible'' if, either, their LHSs are apart or their LHSs unify and their RHSs are the same under the substitution induced by the unification.<br />
<br />
Some examples are in order:<br />
<haskell><br />
type family F a where<br />
F Int = Bool<br />
F Bool = Char<br />
F a = Bool<br />
<br />
type family And (a :: Bool) (b :: Bool) :: Bool where<br />
And False c = False<br />
And True d = d<br />
And e False = False<br />
And f True = f<br />
And g g = g<br />
</haskell><br />
<br />
In <hask>F</hask>, all pairs of equations are compatible except the second and third. The first two are compatible because their LHSs are apart. The first and third are compatible because the unifying substitution leads the RHSs to be the same. But, the second and third are not compatible because neither of these conditions holds. As a result, GHC will not use the third equation to simplify a target unless that target is apart from <hask>Bool</hask>.<br />
<br />
In <hask>And</hask>, ''every'' pair of equations is compatible, meaning GHC never has to make the extra apartness check during simplification.<br />
<br />
Why do all of this? It's a matter of type safety. Consider this example:<br />
<br />
<haskell><br />
type family J a b where<br />
J a a = Int<br />
J a b = Bool<br />
</haskell><br />
<br />
Say GHC selected the second branch just because the first doesn't apply at the moment, because two type variables are distinct. The problem is that those variables might later be instantiated at the same value, and then the first branch would have applied. You can convince this sort of inconsistency to produce <hask>unsafeCoerce</hask>.<br />
<br />
It gets worse. GHC has no internal notion of inequality, so it can't use previous, failed term-level GADT pattern matches to refine its type assumptions. For example:<br />
<br />
<haskell><br />
data G :: * -> * where<br />
GInt :: G Int<br />
GBool :: G Bool<br />
<br />
type family Foo (a :: *) :: * where<br />
Foo Int = Char<br />
Foo a = Double<br />
<br />
bar :: G a -> Foo a<br />
bar GInt = 'x'<br />
bar _ = 3.14<br />
</haskell><br />
<br />
The last line will fail to typecheck, because GHC doesn't know that the type variable <hask>a</hask> can't be <hask>Int</hask> here, even though it's obvious. The only general way to fix this is to have inequality evidence introduced into GHC, and that's a big deal and we don't know if we have the motivation for such a change yet.<br />
<br />
==== Associated type instances ====<br />
<br />
When an associated family instance is declared within a type class instance, we drop the <hask>instance</hask> keyword in the family instance. So, the <hask>[e]</hask> instance for <hask>Elem</hask> becomes:<br />
<haskell><br />
instance (Eq (Elem [e])) => Collects ([e]) where<br />
type Elem [e] = e<br />
...<br />
</haskell><br />
The most important point about associated family instances is that the type indexes corresponding to class parameters must be identical to the type given in the instance head; here this is <hask>[e]</hask>, which coincides with the only class parameter.<br />
<br />
Instances for an associated family can only appear as part of instance declarations of the class in which the family was declared - just as with the equations of the methods of a class. Also in correspondence to how methods are handled, declarations of associated types can be omitted in class instances. If an associated family instance is omitted, the corresponding instance type is not inhabited; i.e., only diverging expressions, such as <hask>undefined</hask>, can assume the type.<br />
<br />
==== Overlap ====<br />
<br />
The instance declarations of an open type family used in a single program must be compatible, in the form defined above. This condition is independent of whether the type family is associated or not, and it is not only a matter of consistency, but one of type safety. <br />
<br />
Here are two examples to illustrate the condition under which overlap is permitted.<br />
<haskell><br />
type instance F (a, Int) = [a]<br />
type instance F (Int, b) = [b] -- overlap permitted<br />
<br />
type instance G (a, Int) = [a]<br />
type instance G (Char, a) = [a] -- ILLEGAL overlap, as [Char] /= [Int]<br />
</haskell><br />
<br />
==== Decidability ====<br />
<br />
In order to guarantee that type inference in the presence of type families is decidable, we need to place a number of additional restrictions on the formation of type instance declarations (c.f., Definition 5 (Relaxed Conditions) of [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking with Open Type Functions]). Instance declarations have the general form<br />
<haskell><br />
type instance F t1 .. tn = t<br />
</haskell><br />
where we require that for every type family application <hask>(G s1 .. sm)</hask> in <hask>t</hask>, <br />
# <hask>s1 .. sm</hask> do not contain any type family constructors,<br />
# the total number of symbols (data type constructors and type variables) in <hask>s1 .. sm</hask> is strictly smaller than in <hask>t1 .. tn</hask>, and<br />
# for every type variable <hask>a</hask>, <hask>a</hask> occurs in <hask>s1 .. sm</hask> at most as often as in <hask>t1 .. tn</hask>.<br />
These restrictions are easily verified and ensure termination of type inference. However, they are not sufficient to guarantee completeness of type inference in the presence of, so called, ''loopy equalities'', such as <hask>a ~ [F a]</hask>, where a recursive occurrence of a type variable is underneath a family application and data constructor application - see the above mentioned paper for details. <br />
<br />
If the option <tt>-XUndecidableInstances</tt> is passed to the compiler, the above restrictions are not enforced and it is on the programmer to ensure termination of the normalisation of type families during type inference.<br />
<br />
=== Equality constraints ===<br />
<br />
Type context can include equality constraints of the form <hask>t1 ~ t2</hask>, which denote that the types <hask>t1</hask> and <hask>t2</hask> need to be the same. In the presence of type families, whether two types are equal cannot generally be decided locally. Hence, the contexts of function signatures may include equality constraints, as in the following example:<br />
<haskell><br />
sumCollects :: (Collects c1, Collects c2, Elem c1 ~ Elem c2) => c1 -> c2 -> c2<br />
</haskell><br />
where we require that the element type of <hask>c1</hask> and <hask>c2</hask> are the same. In general, the types <hask>t1</hask> and <hask>t2</hask> of an equality constraint may be arbitrary monotypes; i.e., they may not contain any quantifiers, independent of whether higher-rank types are otherwise enabled.<br />
<br />
Equality constraints can also appear in class and instance contexts. The former enable a simple translation of programs using functional dependencies into programs using family synonyms instead. The general idea is to rewrite a class declaration of the form<br />
<haskell><br />
class C a b | a -> b<br />
</haskell><br />
to<br />
<haskell><br />
class (F a ~ b) => C a b where<br />
type F a<br />
</haskell><br />
That is, we represent every functional dependency (FD) <hask>a1 .. an -> b</hask> by an FD type family <hask>F a1 .. an</hask> and a superclass context equality <hask>F a1 .. an ~ b</hask>, essentially giving a name to the functional dependency. In class instances, we define the type instances of FD families in accordance with the class head. Method signatures are not affected by that process.<br />
<br />
== Frequently asked questions ==<br />
<br />
=== Comparing type families and functional dependencies ===<br />
<br />
Functional dependencies cover some of the same territory as type families. How do the two compare?<br />
There are some articles about this question:<br />
<br />
* Experiences in converting functional dependencies to type families: "[[Functional dependencies vs. type families]]"<br />
* [http://hackage.haskell.org/trac/ghc/wiki/TFvsFD GHC trac] on a comparison of functional dependencies and type families<br />
<br />
=== Injectivity, type inference, and ambiguity ===<br />
<br />
A common problem is this<br />
<haskell><br />
type family F a<br />
<br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g :: F Int -> F Int<br />
g x = f x<br />
</haskell><br />
The compiler complains about the definition of <tt>g</tt> saying<br />
<code><br />
Couldn't match expected type `F Int' against inferred type `F a1'<br />
</code><br />
In type-checking <tt>g</tt>'s right hand side GHC discovers (by instantiating <tt>f</tt>'s type with a fresh type variable) that it has type <tt>F a1 -> F a1</tt> for some as-yet-unknown type <tt>a1</tt>. Now it tries to make the inferred type match <tt>g</tt>'s type signature. Well, you say, just make <tt>a1</tt> equal to <tt>Int</tt> and you are done. True, but what if there were these instances<br />
<haskell><br />
type instance F Int = Bool<br />
type instance F Char = Bool<br />
</haskell><br />
Then making <tt>a1</tt> equal to <tt>Char</tt> would ''also'' make the two types equal. Because there is (potentially) more than one choice, the program is rejected.<br />
<br />
However (and confusingly) if you omit the type signature on <tt>g</tt> altogether, thus<br />
<haskell><br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g x = f x<br />
</haskell><br />
GHC will happily infer the type <tt>g :: F a -> F a</tt>. But you can't ''write'' that type signature or, indeed, the more specific one above. (Arguably this behaviour, where GHC ''infers'' a type it can't ''check'', is very confusing. I suppose we could make GHC reject both programs, with and without type signatures.)<br />
<br />
'''What is the problem?''' The nub of the issue is this: knowing that <tt>F t1</tt>=<tt>F t2</tt> does ''not'' imply that <tt>t1</tt> = <tt>t2</tt>.<br />
The difficulty is that the type function <tt>F</tt> need not be ''injective''; it can map two distinct types to the same type. For an injective type constructor like <tt>Maybe</tt>, if we know that <tt>Maybe t1</tt> = <tt>Maybe t2</tt>, then we know that <tt>t1</tt> = <tt>t2</tt>. But not so for non-injective type functions.<br />
<br />
The problem starts with <tt>f</tt>. Its type is ''ambiguous''; even if I know the argument and result types for <tt>f</tt>, I cannot use that to find the type at which <tt>a</tt> should be instantiated. (So arguably, <tt>f</tt> should be rejected as having an ambiguous type, and probably will be in future.) The situation is well known in type classes: <br />
<haskell><br />
bad :: (Read a, Show a) => String -> String<br />
bad x = show (read x)<br />
</haskell><br />
At a call of <tt>bad</tt> one cannot tell at what type <tt>a</tt> should be instantiated.<br />
<br />
The only solution is to avoid ambiguous types. In the type signature of a function, <br />
* Ensure that every type variable occurs in the part after the "<tt>=></tt>"<br />
* Ensure that every type variable appears at least once outside a type function call.<br />
Alternatively, you can use data families, which create new types and are therefore injective. The following code works:<br />
<br />
<haskell>data family F a<br />
<br />
f :: F a -> F a<br />
f = undefined<br />
<br />
g :: F Int -> F Int<br />
g x = f x</haskell><br />
<br />
== References ==<br />
<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKPM05.html Associated Types with Class.] Manuel M. T. Chakravarty, Gabriele Keller, Simon Peyton Jones, and Simon Marlow. In ''Proceedings of The 32nd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL'05)'', pages 1-13, ACM Press, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/CKP05.html Associated Type Synonyms.] Manuel M. T. Chakravarty, Gabriele Keller, and Simon Peyton Jones. In ''Proceedings of The Tenth ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 241-253, 2005.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SCPD07.html System F with Type Equality Coercions.] Martin Sulzmann, Manuel M. T. Chakravarty, Simon Peyton Jones, and Kevin Donnelly. In ''Proceedings of The Third ACM SIGPLAN Workshop on Types in Language Design and Implementation'', ACM Press, 2007.<br />
* [http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html Type Checking With Open Type Functions.] Tom Schrijvers, Simon Peyton-Jones, Manuel M. T. Chakravarty, Martin Sulzmann. In ''Proceedings of The 13th ACM SIGPLAN International Conference on Functional Programming'', ACM Press, pages 51-62, 2008.<br />
* [[Simonpj/Talk:FunWithTypeFuns | Fun with Type Functions]] Oleg Kiselyov, Simon Peyton Jones, Chung-chieh Shan (the source for this paper can be found at http://patch-tag.com/r/schoenfinkel/typefunctions/wiki ) <br />
<br />
[[Category:Type-level programming]]<br />
[[Category:Language extensions]]<br />
[[Category:GHC|Indexed types]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Implicit_parameters&diff=61291Implicit parameters2016-11-14T00:28:48Z<p>Ryantm: </p>
<hr />
<div>{{GHCUsersGuide|glasgow_exts|implicit-parameters|an Implicit Parameters section}}<br />
<br />
Working example:<br />
<br />
{-# LANGUAGE ImplicitParams #-}<br />
<br />
import Data.List (sortBy)<br />
<br />
sortBy' :: (?cmp :: a -> a -> Ordering) => [a] -> [a]<br />
sortBy' = sortBy ?cmp<br />
<br />
sort :: Ord a => [a] -> [a]<br />
sort = let ?cmp = compare in sortBy'<br />
<br />
main = putStrLn (show (sort [3,1,2]))<br />
<br />
[[Category:Language extensions]]<br />
[[Category:GHC]]<br />
[[Category:Stub articles]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Implicit_parameters&diff=61290Implicit parameters2016-11-13T23:03:46Z<p>Ryantm: </p>
<hr />
<div>{{GHCUsersGuide|glasgow_exts|implicit-parameters|Implicit Parameters section}}<br />
<br />
Working example:<br />
<br />
{-# LANGUAGE ImplicitParams #-}<br />
<br />
import Data.List (sortBy)<br />
<br />
sortBy' :: (?cmp :: a -> a -> Ordering) => [a] -> [a]<br />
sortBy' = sortBy ?cmp<br />
<br />
sort :: Ord a => [a] -> [a]<br />
sort = let ?cmp = compare in sortBy'<br />
<br />
main = putStrLn (show (sort [3,1,2]))<br />
<br />
[[Category:Language extensions]]<br />
[[Category:GHC]]<br />
[[Category:Stub articles]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Multi-parameter_type_class&diff=61289Multi-parameter type class2016-11-13T23:03:25Z<p>Ryantm: </p>
<hr />
<div>[[Category:Language extensions]]<br />
[[Category:Glossary]]<br />
[[Category:Stub articles]]<br />
<br />
{{GHCUsersGuide|glasgow_exts|multi-parameter-type-classes|a Multi Parameter Type Classes section}}<br />
<br />
== About ==<br />
<br />
Basically, [[type class|type classes]] which can take multiple arguments, such as:<br />
<br />
<haskell><br />
class Monad m => VarMonad m v where<br />
new :: a -> m (v a)<br />
get :: v a -> m a<br />
put :: v a -> a -> m ()<br />
<br />
instance VarMonad IO IORef where ...<br />
instance VarMonad (ST s) (STRef s) where ...<br />
</haskell><br />
<br />
To enable them, use the <hask>{-# LANGUAGE MultiParamTypeClasses #-}</hask> pragma.<br />
<br />
If you think of a single-parameter type class as a set of types, then a multi-parameter type class is a relation between types.<br />
<br />
Naive use of MPTCs may result in ambiguity, so [[functional dependencies]] were developed as a method of resolving that ambiguity, declaring that some subset of the parameters is sufficient to determine the values of the others.<br />
<br />
Some uses of MPTCs with functional dependencies can be replaced with [[type families]].<br />
<br />
The above example can even be implemented in<br />
[[Mutable variable|plain Haskell 98]].<br />
<br />
== Also see ==<br />
<br />
[http://hackage.haskell.org/trac/haskell-prime/wiki/MultiParamTypeClasses The Haskell' page]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Rank-N_types&diff=61288Rank-N types2016-11-13T23:02:58Z<p>Ryantm: </p>
<hr />
<div>[[Category:Language extensions]]<br />
<br />
{{GHCUsersGuide|glasgow_exts|arbitrary-rank-polymorphism|an Arbitrary Rank Polymorphism section}}<br />
<br />
== About ==<br />
<br />
Normal Haskell '98 types are considered Rank-1 types. A Haskell '98 type signature such as<br />
<haskell>a -> b -> a</haskell><br />
implies that the type variables are universally quantified like so:<br />
<haskell>forall a b. a -> b -> a</haskell><br />
<hask>forall</hask> can be floated out of the right-hand side of <hask>-></hask> if it appears there, so:<br />
<haskell>forall a. a -> (forall b. b -> a)</haskell><br />
is also a Rank-1 type because it is equivalent to the previous signature.<br />
<br />
However, a <hask>forall</hask> appearing within the left-hand side of <hask>(->)</hask> cannot be moved up, and therefore forms another level or rank. The type is labeled "Rank-N" where N is the number of <hask>forall</hask>s which are nested and cannot be merged with a previous one. For example:<br />
<br />
<hask>(forall a. a -> a) -> (forall b. b -> b)</hask><br />
<br />
is a Rank-2 type because the latter <hask>forall</hask> can be moved to the start but the former one cannot. Therefore, there are two levels of universal quantification.<br />
<br />
Rank-N type reconstruction is undecidable in general, and some explicit type annotations are required in their presence.<br />
<br />
Rank-2 or Rank-N types may be specifically enabled by the language extensions<br />
<hask>{-# LANGUAGE Rank2Types #-}</hask> or <hask>{-# LANGUAGE RankNTypes #-}</hask>.<br />
<br />
== Church-encoded Lists ==<br />
Church-encoded lists use RankNTypes too, as seen in [http://stackoverflow.com/a/15593349/849891 a StackOverflow answer by sacundim]:<br />
<haskell> <br />
-- | Laws:<br />
--<br />
-- > runList xs cons nil == xs<br />
-- > runList (fromList xs) f z == foldr f z xs<br />
-- > foldr f z (toList xs) == runList xs f z<br />
newtype ChurchList a = <br />
ChurchList { runList :: forall r. (a -> r -> r) -> r -> r }<br />
<br />
-- | Make a 'ChurchList' out of a regular list.<br />
fromList :: [a] -> ChurchList a<br />
fromList xs = ChurchList $ \k z -> foldr k z xs<br />
<br />
-- | Turn a 'ChurchList' into a regular list.<br />
toList :: ChurchList a -> [a]<br />
toList xs = runList xs (:) []<br />
<br />
-- | The 'ChurchList' counterpart to '(:)'. Unlike 'DList', whose<br />
-- implementation uses the regular list type, 'ChurchList' abstracts<br />
-- over it as well.<br />
cons :: a -> ChurchList a -> ChurchList a<br />
cons x xs = ChurchList $ \k z -> k x (runList xs k z)<br />
<br />
-- | Append two 'ChurchList's. This runs in O(1) time. Note that<br />
-- there is no need to materialize the lists as @[a]@.<br />
append :: ChurchList a -> ChurchList a -> ChurchList a<br />
append xs ys = ChurchList $ \k z -> runList xs k (runList ys k z)<br />
<br />
-- i.e.,<br />
<br />
nil = {- fromList [] = ChurchList $ \k z -> foldr k z []<br />
= -} ChurchList $ \k z -> z<br />
<br />
singleton x = {- cons x nil = ChurchList $ \k z -> k x (runList nil k z) <br />
= -} ChurchList $ \k z -> k x z<br />
<br />
snoc xs x = {- append xs $ singleton x<br />
= ChurchList $ \k z -> runList xs k (runList (singleton x) k z) <br />
= -} ChurchList $ \k z -> runList xs k (k x z)<br />
</haskell><br />
<br />
== Relation to Existentials ==<br />
<br />
In order to unpack an existential type, you need a polymorphic function that works on any type that could be stored in the existential. This leads to a natural relation between higher-rank types and existentials; and an encoding of existentials in terms of higher rank types in continuation-passing style.<br />
<br />
In general, you can replace<br />
<haskell>data T a1 .. ai = forall t1 .. tj. constraints => Constructor e1 .. ek</haskell><br />
(where <hask>e1..ek</hask> are types in terms of <hask>a1..ai</hask> and <hask>t1..tj</hask>)<br />
<br />
<haskell>Constructor exp1 .. expk -- application of the constructor</haskell><br />
<br />
<haskell>case e of (Constructor pat1 .. patk) -> res</haskell><br />
<br />
with<br />
<br />
<haskell>data T' a1 .. ai = Constructor' (forall b. (forall t1..tj. constraints => e1 -> e2 -> ... -> ek -> b) -> b)</haskell><br />
<br />
<haskell>Constructor' (\f -> f exp1 .. expk)</haskell><br />
<br />
<haskell>case e of (Constructor' f) -> let k pat1 .. patk = res in f k</haskell><br />
<br />
== See also ==<br />
<br />
* [http://hackage.haskell.org/trac/haskell-prime/wiki/RankNTypes Rank-N types] on the Haskell' website.<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#arbitrary-rank-polymorphism The GHC User's Guide on higher-ranked polymorphism].</div>Ryantmhttps://wiki.haskell.org/index.php?title=Rank-N_types&diff=61287Rank-N types2016-11-13T23:02:43Z<p>Ryantm: </p>
<hr />
<div>[[Category:Language extensions]]<br />
<br />
{{GHCUsersGuide|glasgow_exts.html|arbitrary-rank-polymorphism|an Arbitrary Rank Polymorphism section}}<br />
<br />
== About ==<br />
<br />
Normal Haskell '98 types are considered Rank-1 types. A Haskell '98 type signature such as<br />
<haskell>a -> b -> a</haskell><br />
implies that the type variables are universally quantified like so:<br />
<haskell>forall a b. a -> b -> a</haskell><br />
<hask>forall</hask> can be floated out of the right-hand side of <hask>-></hask> if it appears there, so:<br />
<haskell>forall a. a -> (forall b. b -> a)</haskell><br />
is also a Rank-1 type because it is equivalent to the previous signature.<br />
<br />
However, a <hask>forall</hask> appearing within the left-hand side of <hask>(->)</hask> cannot be moved up, and therefore forms another level or rank. The type is labeled "Rank-N" where N is the number of <hask>forall</hask>s which are nested and cannot be merged with a previous one. For example:<br />
<br />
<hask>(forall a. a -> a) -> (forall b. b -> b)</hask><br />
<br />
is a Rank-2 type because the latter <hask>forall</hask> can be moved to the start but the former one cannot. Therefore, there are two levels of universal quantification.<br />
<br />
Rank-N type reconstruction is undecidable in general, and some explicit type annotations are required in their presence.<br />
<br />
Rank-2 or Rank-N types may be specifically enabled by the language extensions<br />
<hask>{-# LANGUAGE Rank2Types #-}</hask> or <hask>{-# LANGUAGE RankNTypes #-}</hask>.<br />
<br />
== Church-encoded Lists ==<br />
Church-encoded lists use RankNTypes too, as seen in [http://stackoverflow.com/a/15593349/849891 a StackOverflow answer by sacundim]:<br />
<haskell> <br />
-- | Laws:<br />
--<br />
-- > runList xs cons nil == xs<br />
-- > runList (fromList xs) f z == foldr f z xs<br />
-- > foldr f z (toList xs) == runList xs f z<br />
newtype ChurchList a = <br />
ChurchList { runList :: forall r. (a -> r -> r) -> r -> r }<br />
<br />
-- | Make a 'ChurchList' out of a regular list.<br />
fromList :: [a] -> ChurchList a<br />
fromList xs = ChurchList $ \k z -> foldr k z xs<br />
<br />
-- | Turn a 'ChurchList' into a regular list.<br />
toList :: ChurchList a -> [a]<br />
toList xs = runList xs (:) []<br />
<br />
-- | The 'ChurchList' counterpart to '(:)'. Unlike 'DList', whose<br />
-- implementation uses the regular list type, 'ChurchList' abstracts<br />
-- over it as well.<br />
cons :: a -> ChurchList a -> ChurchList a<br />
cons x xs = ChurchList $ \k z -> k x (runList xs k z)<br />
<br />
-- | Append two 'ChurchList's. This runs in O(1) time. Note that<br />
-- there is no need to materialize the lists as @[a]@.<br />
append :: ChurchList a -> ChurchList a -> ChurchList a<br />
append xs ys = ChurchList $ \k z -> runList xs k (runList ys k z)<br />
<br />
-- i.e.,<br />
<br />
nil = {- fromList [] = ChurchList $ \k z -> foldr k z []<br />
= -} ChurchList $ \k z -> z<br />
<br />
singleton x = {- cons x nil = ChurchList $ \k z -> k x (runList nil k z) <br />
= -} ChurchList $ \k z -> k x z<br />
<br />
snoc xs x = {- append xs $ singleton x<br />
= ChurchList $ \k z -> runList xs k (runList (singleton x) k z) <br />
= -} ChurchList $ \k z -> runList xs k (k x z)<br />
</haskell><br />
<br />
== Relation to Existentials ==<br />
<br />
In order to unpack an existential type, you need a polymorphic function that works on any type that could be stored in the existential. This leads to a natural relation between higher-rank types and existentials; and an encoding of existentials in terms of higher rank types in continuation-passing style.<br />
<br />
In general, you can replace<br />
<haskell>data T a1 .. ai = forall t1 .. tj. constraints => Constructor e1 .. ek</haskell><br />
(where <hask>e1..ek</hask> are types in terms of <hask>a1..ai</hask> and <hask>t1..tj</hask>)<br />
<br />
<haskell>Constructor exp1 .. expk -- application of the constructor</haskell><br />
<br />
<haskell>case e of (Constructor pat1 .. patk) -> res</haskell><br />
<br />
with<br />
<br />
<haskell>data T' a1 .. ai = Constructor' (forall b. (forall t1..tj. constraints => e1 -> e2 -> ... -> ek -> b) -> b)</haskell><br />
<br />
<haskell>Constructor' (\f -> f exp1 .. expk)</haskell><br />
<br />
<haskell>case e of (Constructor' f) -> let k pat1 .. patk = res in f k</haskell><br />
<br />
== See also ==<br />
<br />
* [http://hackage.haskell.org/trac/haskell-prime/wiki/RankNTypes Rank-N types] on the Haskell' website.<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#arbitrary-rank-polymorphism The GHC User's Guide on higher-ranked polymorphism].</div>Ryantmhttps://wiki.haskell.org/index.php?title=Functional_dependencies&diff=61286Functional dependencies2016-11-13T22:59:59Z<p>Ryantm: </p>
<hr />
<div>[[Category:Glossary]]<br />
[[Category:Language extensions]]<br />
Functional dependencies are used to constrain the parameters of type classes. They let you state that in a [[multi-parameter type class]], one of the [[parameter]]s can be determined from the others, so that the [[parameter]] determined by the others can, for example, be the return type but none of the argument types of some of the methods.<br />
<br />
{{GHCUsersGuide|glasgow_exts|functional-dependencies|a Functional Dependencies section}}<br />
<br />
==Examples==<br />
Suppose you want to implement some code to perform simple [[linear algebra]]:<br />
<haskell><br />
data Vector = Vector Int Int deriving (Eq, Show)<br />
data Matrix = Matrix Vector Vector deriving (Eq, Show)<br />
</haskell><br />
You want these to behave as much like numbers as possible. So you might start by overloading Haskell's Num class:<br />
<haskell><br />
instance Num Vector where<br />
Vector a1 b1 + Vector a2 b2 = Vector (a1+a2) (b1+b2)<br />
Vector a1 b1 - Vector a2 b2 = Vector (a1-a2) (b1-b2)<br />
{- ... and so on ... -}<br />
<br />
instance Num Matrix where<br />
Matrix a1 b1 + Matrix a2 b2 = Matrix (a1+a2) (b1+b2)<br />
Matrix a1 b1 - Matrix a2 b2 = Matrix (a1-a2) (b1-b2)<br />
{- ... and so on ... -}<br />
</haskell><br />
The problem comes when you want to start multiplying quantities. You really need a multiplication function which overloads to different types:<br />
<haskell><br />
(*) :: Matrix -> Matrix -> Matrix<br />
(*) :: Matrix -> Vector -> Vector<br />
(*) :: Matrix -> Int -> Matrix<br />
(*) :: Int -> Matrix -> Matrix<br />
{- ... and so on ... -}<br />
</haskell><br />
How do we specify a type class which allows all these possibilities?<br />
<br />
We could try this:<br />
<haskell><br />
class Mult a b c where<br />
(*) :: a -> b -> c<br />
<br />
instance Mult Matrix Matrix Matrix where<br />
{- ... -}<br />
<br />
instance Mult Matrix Vector Vector where<br />
{- ... -}<br />
</haskell><br />
That, however, isn't really what we want. As it stands, even a simple expression like this has an ambiguous type unless you supply an additional type declaration on the intermediate expression:<br />
<haskell><br />
m1, m2, m3 :: Matrix<br />
(m1 * m2) * m3 -- type error; type of (m1*m2) is ambiguous<br />
(m1 * m2) :: Matrix * m3 -- this is ok<br />
</haskell><br />
After all, nothing is stopping someone from coming along later and adding another instance:<br />
<haskell><br />
instance Mult Matrix Matrix (Maybe Char) where<br />
{- whatever -}<br />
</haskell><br />
The problem is that <hask>c</hask> shouldn't really be a free type variable. When you know the types of the things that you're multiplying, the result type should be determined from that information alone.<br />
<br />
You can express this by specifying a functional dependency, or fundep for short:<br />
<haskell><br />
class Mult a b c | a b -> c where<br />
(*) :: a -> b -> c<br />
</haskell><br />
This tells Haskell that <hask>c</hask> is uniquely determined from <hask>a</hask> and <hask>b</hask>.<br />
<br />
Fundeps have lots more uses than just implementing C++-style function overloading, of course. See [http://web.cecs.pdx.edu/~mpj/pubs/fundeps.html the paper] by Mark P. Jones for further details.<br />
<br />
Fundeps are not standard Haskell 98. (Nor are [[multi-parameter type class]]es, for that matter.) They are, however, supported at least in [[GHC]] and [[Hugs]] and will almost certainly end up in Haskell'.<br />
<br />
[[User:AndrewBromage]]<br />
<br />
== Another example ==<br />
<br />
The following example makes use of the FlexibleInstances, MultiParamTypeClasses and FunctionalDependencies GHC extensions.<br />
<br />
<haskell><br />
-- Read as: "container" type determines "elem" type.<br />
class Extract container elem | container -> elem where<br />
extract :: container -> elem<br />
</haskell><br />
<br />
The functional dependency "container -> elem" promises that we won't declare multiple instances with the same "container" type.<br />
<br />
<haskell><br />
instance Extract (a,b) a where<br />
extract (x,_) = x<br />
</haskell><br />
<br />
Because of the functional dependency we can't have the previous instance *and* this one:<br />
<br />
<haskell>-- instance Extract (a,b) b where ...</haskell><br />
<br />
Because of the functional dependency we can say:<br />
<br />
<haskell>v = extract ('x', 3)</haskell><br />
<br />
and it will infer the type <haskell>v :: Char</haskell><br />
<br />
Without the functional dependency, both instances above would be allowed, and the type of v would be potentially ambiguous. Even if only one instance is defined, the type system will not figure it out without the functional dependency.<br />
<br />
== Tutorials ==<br />
<br />
* [http://www.cs.chalmers.se/~hallgren/Papers/wm01.html Fun with functional dependencies], Thomas Hallgren (2001)<br />
* [[User:ConradParker/InstantInsanity | Type-Level Instant Insanity]], Conrad Parker (2007)<br />
<br />
== See also ==<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#functional-dependencies GHC documentation]<br />
* [[Functional dependencies vs. type families]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Generalised_algebraic_datatype&diff=61285Generalised algebraic datatype2016-11-13T22:59:33Z<p>Ryantm: </p>
<hr />
<div>{{GHCUsersGuide|glasgow_exts|generalised-algebraic-data-types-gadts|a GADTs section}}<br />
<br />
== Papers ==<br />
<br />
See also [[Research papers/Type systems#Generalised Algebraic Data Types (GADTs)|research papers on type systems]].<br />
<br />
* A short description on generalised algebraic datatypes here [http://www.haskell.org/ghc/docs/latest/html/users_guide/data-type-extensions.html#gadt as GHC language features].<br />
* Another description with links on [http://hackage.haskell.org/trac/haskell-prime/wiki/GADTs Haskell' wiki].<br />
* [http://ecommons.library.cornell.edu/handle/1813/5614 First-Class Phantom Types] by James Cheney and Ralf Hinze<br />
* [http://cristal.inria.fr/~fpottier/publis/pottier-regis-gianas-05.pdf Stratified type inference for generalized algebraic data types] by François Pottier and Yann Régis-Gianas. It contains also a lot of links to other papers on GADTs.<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/papers/gadt/index.htm Simple unification-based type inference for GADTs] by Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, and Geoffrey Washburn. (Revised April 2006.)<br />
* [http://www.cs.mu.oz.au/~sulzmann/manuscript/simple-translate-gadts.ps Translating Generalized Algebraic Data Types to System F] written by [http://www.cs.mu.oz.au/~sulzmann/ Martin Sulzmann] and Meng Wang. [http://www.cs.mu.oz.au/~sulzmann/2005.html Many other papers]. The talk mentions also the notion of [[phantom type]], and [[existential type]], and [[type witness]].<br />
<br />
== Motivating example ==<br />
<br />
Generalised Algebraic Datatypes (GADTs) are datatypes for which a constructor has a non standard type. Indeed, in type systems incorporating GADTs, there are very few restrictions on the type that the data constructors can take. To show you how this could be useful, we will implement an evaluator for the typed SK calculus. Note that the K combinator is operationally similar to<br />
<math>\lambda\;x\;y\;.\;x</math><br />
and, similarly, S is similar to the combinator<br />
<math>\lambda\;x\;y\;z\;.\;x\;z\;(\;y\;z\;)</math><br />
which, in simply typed lambda calculus, have types<br />
<math>a \rightarrow b \rightarrow a </math><br />
and<br />
<math>(a \rightarrow b \rightarrow c) \rightarrow (a \rightarrow b) \rightarrow a \rightarrow c </math><br />
Without GADTs we would have to write something like this:<br />
<haskell><br />
data Term = K | S | Term :@ Term <br />
infixl 6 :@<br />
</haskell><br />
With GADTs, however, we can have the terms carry around more type information and create more interesting terms, like so:<br />
<haskell><br />
data Term x where<br />
K :: Term (a -> b -> a)<br />
S :: Term ((a -> b -> c) -> (a -> b) -> a -> c)<br />
Const :: a -> Term a<br />
(:@) :: Term (a -> b) -> (Term a) -> Term b<br />
infixl 6 :@<br />
</haskell><br />
now we can write a small step evaluator:<br />
<haskell><br />
eval::Term a -> Term a<br />
eval (K :@ x :@ y) = x<br />
eval (S :@ x :@ y :@ z) = x :@ z :@ (y :@ z)<br />
eval x = x<br />
</haskell><br />
Since the types of the so-called object language, being the typed SK calculus, are mimicked by the type system in our meta language, being Haskell, we have a pretty convincing argument that the evaluator won't mangle our types. We say that typing is preserved under evaluation (preservation.) Note that this is an argument and not a proof.<br />
<br />
This, however, comes at a price: let's see what happens when you try to convert strings into our object language:<br />
<haskell><br />
parse "K" = K<br />
parse "S" = S<br />
</haskell><br />
you'll get a nasty error like so:<br />
<br />
Occurs check: cannot construct the infinite type: c = b -> c<br />
Expected type: Term ((a -> b -> c) -> (a -> b) -> a -> b -> c)<br />
Inferred type: Term ((a -> b -> c) -> (a -> b) -> a -> c)<br />
In the definition of `foo': foo "S" = S<br />
<br />
One could, however, reason that parse has type: <hask>String -> exists a. Term a</hask>, see also [[Existential type]].<br />
<br />
== Example with lists ==<br />
<br />
here's another, smaller example:<br />
<haskell><br />
data Empty<br />
data NonEmpty<br />
data List x y where<br />
Nil :: List a Empty<br />
Cons:: a -> List a b -> List a NonEmpty<br />
<br />
safeHead:: List x NonEmpty -> x<br />
safeHead (Cons a b) = a<br />
</haskell><br />
<br />
now safeHead can only be applied to non empty lists, and will never evaluate to bottom. This too comes at a cost; consider the function:<br />
<br />
<haskell><br />
silly 0 = Nil<br />
silly 1 = Cons 1 Nil<br />
</haskell><br />
<br />
yields an objection from ghc:<br />
Couldn't match `Empty' against `NonEmpty'<br />
Expected type: List a Empty<br />
Inferred type: List a NonEmpty<br />
In the application `Cons 1 Nil'<br />
In the definition of `silly': silly 1 = Cons 1 Nil<br />
<br />
== Parsing Example ==<br />
<br />
Note that GADTs provide a rather nice platform for embedded domain specific languages. In particular, they allow an [[EDSL]] to use Haskell's type system for its own purposes. As a simple example, we might have an EDSL for simple (regexp-like) parsers that looks something like:<br />
<br />
<haskell><br />
data Parser tok a where<br />
Zero :: Parser tok ()<br />
One :: Parser tok ()<br />
Check :: (tok -> Bool) -> Parser tok tok<br />
Satisfy :: ([tok] -> Bool) -> Parser tok [tok]<br />
Push :: tok -> Parser tok a -> Parser tok a<br />
Plus :: Parser tok a -> Parser tok b -> Parser tok (Either a b)<br />
Times :: Parser tok a -> Parser tok b -> Parser tok (a,b)<br />
Star :: Parser tok a -> Parser tok [a]<br />
</haskell><br />
<br />
An evaluator/parser is then straightforward. Below it's written monadically for<br />
convenience, but this also means that we could generalise the return type to being in any MonadPlus. Note that an advantage of this representation which we don't show here is that we could also write a function which applies algebraic rules to the structure to try to simplify the parser before running it. (Though if we were really concerned with efficiency, we'd probably also need a couple more primitives.)<br />
<br />
<haskell><br />
parse :: Parser tok a -> [tok] -> Maybe a<br />
<br />
-- Zero always fails.<br />
parse Zero ts = mzero<br />
<br />
-- One matches only the empty string.<br />
parse One [] = return ()<br />
parse One _ = mzero<br />
<br />
-- Check p matches a string with exactly one token t such that p t holds.<br />
parse (Check p) [t] = if p t then return t else mzero<br />
parse (Check p) _ = mzero<br />
<br />
-- Satisfy p any string such that p ts holds.<br />
parse (Satisfy p) xs = if p xs then return xs else mzero<br />
<br />
-- Push t x matches a string ts when x matches (t:ts).<br />
parse (Push t x) ts = parse x (t:ts)<br />
<br />
-- Plus x y matches when either x or y does.<br />
parse (Plus x y) ts = liftM Left (parse x ts) `mplus` liftM Right (parse y ts)<br />
<br />
-- Times x y matches the concatenation of x and y.<br />
parse (Times x y) [] = liftM2 (,) (parse x []) (parse y [])<br />
parse (Times x y) (t:ts) = <br />
parse (Times (Push t x) y) ts `mplus`<br />
liftM2 (,) (parse x []) (parse y (t:ts))<br />
<br />
-- Star x matches zero or more copies of x.<br />
parse (Star x) [] = return []<br />
parse (Star x) (t:ts) = do<br />
(v,vs) <- parse (Times x (Star x)) (t:ts)<br />
return (v:vs)<br />
</haskell><br />
<br />
Finally, we might define some examples:<br />
<br />
<haskell><br />
token x = Check (== x)<br />
string xs = Satisfy (== xs)<br />
<br />
p = Times (token 'a') (token 'b')<br />
p1 = Times (Star (token 'a')) (Star (token 'b'))<br />
p2 = Star p1<br />
<br />
blocks :: (Eq tok) => Parser tok [[tok]]<br />
blocks = Star (Satisfy allEqual)<br />
where allEqual xs = and (zipWith (==) xs (drop 1 xs))<br />
<br />
evenOdd = Plus (Star (Times (Check even) (Check odd)))<br />
(Star (Times (Check odd) (Check even)))<br />
<br />
</haskell><br />
<br />
Testing this in ghci:<br />
<pre><br />
*Main> parse p "ab"<br />
Just ('a','b')<br />
*Main> parse p "ac"<br />
Nothing<br />
*Main> parse p1 "aaabbbb"<br />
Just ("aaa","bbbb")<br />
*Main> parse p2 "aaabbbbaabbbbbbbaaabbabab"<br />
Just [("aaa","bbbb"),("aa","bbbbbbb"),("aaa","bb"),("a","b"),("a","b")]<br />
*Main> :t p2<br />
p2 :: Parser Char [([Char], [Char])]<br />
*Main> parse blocks "aaaabbbbbbbbcccccddd"<br />
Just ["aaaa","bbbbbbbb","ccccc","ddd"]<br />
*Main> parse evenOdd [0..9]<br />
Just (Left [(0,1),(2,3),(4,5),(6,7),(8,9)])<br />
*Main> parse evenOdd [1..10]<br />
Just (Right [(1,2),(3,4),(5,6),(7,8),(9,10)])<br />
<br />
</pre><br />
<br />
== Projects containing GADTs ==<br />
<br />
Papers on [[Libraries and tools/Database interfaces/HaskellDB|HaskellDB]] describe problems when GADTs can help (but HaskellDB solves these problems with [[phantom type]]s).<br />
<br />
[[Darcs]] represents motivating examples for GADTs, too -- and uses them.<br />
The motivations are described in David Roundy's FOSDEM slides ([http://physics.oregonstate.edu/~roundyd/talks/fosdem-2006.pdf Implementing the Darcs Patch Formalism and Verifying It]) (see p. 11, 13--14.). The talk mentions also the notions of [[phantom type]], and [[existential type]], and [[type witness]] (see p. 15).<br />
<br />
== See also ==<br />
<br />
* [[Algebraic data type]]<br />
* [[GADTs for dummies]]<br />
* [http://en.wikibooks.org/wiki/Haskell/GADT The Haskell Wikibook section about GADT]<br />
* [http://apfelmus.nfshost.com/blog/2010/06/01-gadts-video.html A video that explains GADTs]<br />
<br />
<br />
[[Category:Glossary]]<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Existential_type&diff=61284Existential type2016-11-13T22:59:03Z<p>Ryantm: </p>
<hr />
<div>__TOC__<br />
This is an extension of Haskell available in [[GHC]]. <br />
<br />
{{GHCUsersGuide|glasgow_exts|existentially-quantified-data-constructors|an Existential Quantification section}}<br />
<br />
==Introduction to existential types==<br />
<br />
=== Overview ===<br />
<br />
Normally when creating a new type using <hask>type</hask>, <hask>newtype</hask>, <hask>data</hask>, etc., every type variable that appears on the right-hand side must also appear on the left-hand side. Existential types are a way of turning this off.<br />
<br />
=== Basics ===<br />
<br />
Existential types can be ''used'' for several different purposes. But what they ''do'' is to 'hide' a type variable on the right-hand side.<br />
<br />
Normally, any type variable appearing on the right must also appear on the left:<br />
<br />
<haskell><br />
data Worker x y = Worker {buffer :: b, input :: x, output :: y}<br />
</haskell><br />
<br />
This is an error, since the type of the buffer isn't specified on the right (it's a type variable rather than a type) but also isn't specified on the left (there's no 'b' in the left part). In Haskell98, you would have to write<br />
<br />
<haskell><br />
data Worker b x y = Worker {buffer :: b, input :: x, output :: y}<br />
</haskell><br />
<br />
That may or may not be an actual problem.<br />
<br />
Usually there is no problem at all with this state of affairs (which is why Haskell98 works this way). However, suppose that a <hask>Worker</hask> can use ''any'' type 'b' so long as it belongs to some particular class. Then every function that uses a <hask>Worker</hask> will have a type like<br />
<br />
<haskell><br />
foo :: (Buffer b) => Worker b Int Int<br />
</haskell><br />
<br />
or something. (In particular, failing to write an explicit type signature will invoke the dreaded [[monomorphism restriction]].) Using existential types, we can avoid this:<br />
<br />
<haskell><br />
data Worker x y = forall b. Buffer b => Worker {buffer :: b, input :: x, output :: y}<br />
<br />
foo :: Worker Int Int<br />
</haskell><br />
<br />
The type of the buffer now does ''not'' appear in the <hask>Worker</hask> type at all.<br />
<br />
This has a number of consequences. First of all, it is now impossible for a function to demand a <hask>Worker</hask> having a specific type of buffer. Second, the type of <hask>foo</hask> can now be derived automatically without needing an explicit type signature. (No [[monomorphism restriction]].) Thirdly, since code now has ''no idea'' what type the <hask>buffer</hask> function returns, you are more limited in what you can do to it.<br />
<br />
In general, when you use a 'hidden' type in this way, you will usually want that type to belong to a specific class, or you will want to pass some functions along that can work on that type. Otherwise you'll have some value belonging to a random unknown type, and you won't be able to ''do'' anything to it!<br />
<br />
Note: You can use existential types to convert a more specific type into a less specific one. (See the examples below.) There is ''no way'' to perform the reverse conversion!<br />
<br />
== Examples ==<br />
<br />
===A short example===<br />
<br />
This illustrates creating a heterogeneous list, all of whose members implement "Show", and progressing through that list to show these items:<br />
<br />
<haskell><br />
data Obj = forall a. (Show a) => Obj a<br />
<br />
xs :: [Obj]<br />
xs = [Obj 1, Obj "foo", Obj 'c']<br />
<br />
doShow :: [Obj] -> String<br />
doShow [] = ""<br />
doShow ((Obj x):xs) = show x ++ doShow xs<br />
</haskell><br />
<br />
With output: <code>doShow xs ==> "1\"foo\"'c'"</code><br />
<br />
===Expanded example - rendering objects in a raytracer===<br />
<br />
====Problem statement====<br />
<br />
In a raytracer, a requirement is to be able to render several different objects (like a ball, mesh or whatever). The first step is a type class for Renderable like so:<br />
<br />
<haskell><br />
class Renderable a where<br />
boundingSphere :: a -> Sphere<br />
hit :: a -> [Fragment] -- returns the "fragments" of all hits with ray<br />
{- ... etc ... -}<br />
</haskell><br />
<br />
To solve the problem, the <hask>hit</hask> function must apply to several objects (like a sphere and a polygon for instance).<br />
<br />
<haskell><br />
hits :: Renderable a => [a] -> [Fragment]<br />
hits xs = sortByDistance $ concatMap hit xs<br />
</haskell><br />
<br />
However, this does not work as written since the elements of the list can be of '''SEVERAL''' different types (like a sphere and a polygon and a mesh etc. etc.) but<br />
lists need to have elements of the same type.<br />
<br />
====The solution====<br />
<br />
Use 'existential types' - an extension to Haskell that can be found in most compilers.<br />
<br />
The following example is based on GHC :<br />
<br />
<haskell><br />
{-# OPTIONS -fglasgow-exts #-}<br />
<br />
{- ...-}<br />
<br />
data AnyRenderable = forall a. Renderable a => AnyRenderable a<br />
<br />
instance Renderable AnyRenderable where<br />
boundingSphere (AnyRenderable a) = boundingSphere a<br />
hit (AnyRenderable a) = hit a<br />
{- ... -}<br />
</haskell><br />
<br />
Now, create lists with type <hask>[AnyRenderable]</hask>, for example,<br />
<haskell><br />
[ AnyRenderable x<br />
, AnyRenderable y<br />
, AnyRenderable z ]<br />
</haskell><br />
where x, y, z can be from different instances of <hask>Renderable</hask>.<br />
=== Dynamic dispatch mechanism of OOP ===<br />
<br />
'''Existential types''' in conjunction with type classes can be used to emulate the dynamic dispatch mechanism of object oriented programming languages. To illustrate this concept I show how a classic example from object oriented programming can be encoded in Haskell.<br />
<br />
<haskell><br />
class Shape_ a where<br />
perimeter :: a -> Double<br />
area :: a -> Double<br />
<br />
data Shape = forall a. Shape_ a => Shape a<br />
<br />
type Radius = Double<br />
type Side = Double<br />
<br />
data Circle = Circle Radius<br />
data Rectangle = Rectangle Side Side<br />
data Square = Square Side<br />
<br />
<br />
instance Shape_ Circle where<br />
perimeter (Circle r) = 2 * pi * r<br />
area (Circle r) = pi * r * r<br />
<br />
instance Shape_ Rectangle where<br />
perimeter (Rectangle x y) = 2*(x + y)<br />
area (Rectangle x y) = x * y<br />
<br />
instance Shape_ Square where<br />
perimeter (Square s) = 4*s<br />
area (Square s) = s*s<br />
<br />
instance Shape_ Shape where<br />
perimeter (Shape shape) = perimeter shape<br />
area (Shape shape) = area shape<br />
<br />
<br />
--<br />
-- Smart constructor<br />
--<br />
<br />
circle :: Radius -> Shape<br />
circle r = Shape (Circle r)<br />
<br />
rectangle :: Side -> Side -> Shape<br />
rectangle x y = Shape (Rectangle x y)<br />
<br />
square :: Side -> Shape<br />
square s = Shape (Square s)<br />
<br />
shapes :: [Shape]<br />
shapes = [circle 2.4, rectangle 3.1 4.4, square 2.1]<br />
</haskell><br />
<br />
(You may see other [[Smart constructors]] for other purposes).<br />
<br />
=== [[Generalised algebraic datatype]] ===<br />
<br />
The type of the <hask>parse</hask> function for [[Generalised algebraic datatype#Motivating example|this GADT]] is a good example to illustrate the concept of existential type.<br />
<br />
=== SomeException ===<br />
<hask>Control.Exception</hask> (see [http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Exception.html documentation]) provides extensible exceptions by making the core exception type, <hask>SomeException</hask>, an existential:<br />
<br />
<haskell><br />
class (Show e, Typeable e) => Exception e where<br />
toException :: e -> SomeException<br />
fromException :: SomeException -> Maybe e<br />
data SomeException = forall a. Exception a => SomeException a<br />
</haskell><br />
<br />
You can define your own exceptions by making them an instance of the <hask>Exception</hask> class. Then there are two basic ways of dealing with exceptions:<br />
#If you have a <hask>SomeException</hask> value, use <hask>fromException</hask>. This returns <hask>Just e</hask> if the exception is the type you want. If it's something else, you get <hask>Nothing</hask>. You could check multiple types using a guard. This is what you'll have to use if you're dealing with <hask>SomeException</hask>s in pure code.<br />
#If you're in IO and have an expression that might throw an exception, <hask>catch</hask> lets you catch it. (There's also a version generalised to other instances of <hask>MonadIO</hask> in the <hask>lifted-base</hask> package). Its second argument takes a handler, which is a function accepting an exception of the type you want. If the first argument throws an exception, <hask>catch</hask> uses the <hask>Typeable</hask> library's typesafe cast to try to convert it to the type you want, then (if it succeeded) passes it to the handler. You can apply <hask>catch</hask> many times to the same expression with handlers for different exception types.<br />
#Even if <hask>fromException</hask> doesn't turn up an exception type you know, and <hask>catch</hask> doesn't catch an exception type you know, you can still <hask>show</hask> the unknown exception, maybe after catching <hask>SomeException</hask>.<br />
<br />
==Alternate methods==<br />
===Concrete data types===<br />
====Universal instance of a Class====<br />
Here one way to simulate existentials (Hawiki note: (Borrowed from somewhere...))<br />
<br />
<br />
Suppose I have a type class Shape a<br />
<haskell><br />
type Point = (Float,Float)<br />
<br />
class Shape a where<br />
draw :: a -> IO ()<br />
translate :: a-> Point -> a<br />
<br />
</haskell><br />
<br />
Then we can pack shapes up into a [[concrete data type]] like this:<br />
<haskell><br />
data SHAPE = SHAPE (IO ()) (Point -> SHAPE)<br />
</haskell><br />
with a function like this<br />
<haskell><br />
packShape :: Shape a => a -> SHAPE<br />
packShape s = SHAPE (draw s) (\(x,y) -> packShape (translate s (x,y)))<br />
</haskell><br />
This would be useful if we needed a list of shapes that we would need to translate and draw.<br />
<br />
In fact we can make <hask>SHAPE</hask> an instance of <hask>Shape</hask>:<br />
<haskell><br />
instance Shape SHAPE where<br />
draw (SHAPE d t) = d<br />
translate (SHAPE d t) = t<br />
</haskell><br />
<br />
So SHAPE is a sort of universal instance.<br />
<br />
====Using constructors and combinators====<br />
Why bother with class <hask>Shape</hask>? Why not just go straight to<br />
<br />
<haskell><br />
data Shape = Shape {<br />
draw :: IO()<br />
translate :: (Int, Int) -> Shape<br />
}<br />
</haskell><br />
<br />
Then you can create a library of shape [[constructor]]s and [[combinator]]s<br />
that each have defined "draw" and "translate" in their "where" clauses.<br />
<br />
<haskell><br />
circle :: (Int, Int) -> Int -> Shape<br />
circle (x,y) r =<br />
Shape draw1 translate1<br />
where<br />
draw1 = ...<br />
translate1 (x1,y1) = circle (x+x1, y+y1) r<br />
<br />
shapeGroup :: [Shape] -> Shape<br />
shapeGroup shapes = Shape draw1 translate1<br />
where<br />
draw1 = mapM_ draw shapes<br />
translate1 v = shapeGroup $ map (translate v) shapes<br />
</haskell><br />
<br />
===Cases that really require existentials===<br />
<br />
There are cases where this sort of trick doesn't work. Here are two examples from a haskell mailing list discussion (from K. Claussen) that don't seem expressible without<br />
existentials. (But maybe one can rethink the whole thing :)<br />
<haskell><br />
data Expr a = Val a | forall b . Apply (Expr (b -> a)) (Expr b)<br />
</haskell><br />
and<br />
<haskell><br />
data Action = forall b . Act (IORef b) (b -> IO ())<br />
</haskell><br />
(Maybe this last one could be done as a <hask>type Act (IORef b) (IORef b -> IO ())</hask> then we could hide the <hask>IORef</hask> as above, that is go ahead and apply the second argument to the first)<br />
<br />
=== Existentials in terms of "forall" ===<br />
It is also possible to express existentials as type expressions directly (without a <hask>data</hask> declaration) with RankNTypes. Taking the above example:<br />
<br />
<haskell>data Obj = forall a. (Show a) => Obj a</haskell><br />
<br />
the type <hask>Obj</hask> is equivalent to:<br />
<br />
<haskell>forall r. (forall a. Show a => a -> r) -> r</haskell><br />
<br />
(the leading <hask>forall r.</hask> is optional unless the expression is part of another expression). The conversions are:<br />
<br />
<haskell><br />
fromObj :: Obj <br />
-> forall r. (forall a. Show a => a -> r) -> r<br />
fromObj (Obj x) k = k x<br />
<br />
toObj :: (forall r. (forall a. Show a => a -> r) -> r) <br />
-> Obj<br />
toObj f = f Obj<br />
</haskell><br />
<br />
== Examples from the [http://www.cs.uu.nl/wiki/Ehc/ Essential Haskell Compiler] project ==<br />
<br />
See the [http://www.cs.uu.nl/wiki/Ehc/#On_EHC documentation on EHC], each paper at the ''Version 4'' part:<br />
* Chapter 8 (EH4) of Atze Dijkstra's [http://www.cs.uu.nl/groups/ST/Projects/ehc/ehc-book.pdf Essential Haskell PhD thesis] (most recent version). A detailed explanation. It explains also that existential types can be expressed in Haskell, but their use is restricted to data declarations, and the notation (using keyword <hask>forall</hask>) may be confusing. In Essential Haskell, existential types can occur not only in data declarations, and a separate keyword <hask>exists</hask> is used for their notation.<br />
* [http://www.cs.uu.nl/wiki/pub/Ehc/WebHome/20050107-eh-intro.pdf Essential Haskell Compiler overview]<br />
* [http://www.cs.uu.nl/wiki/Ehc/Examples#EH_4_forall_and_exists_everywher Examples]<br />
<br />
==See also==<br />
* A mailinglist discussion: http://haskell.org/pipermail/haskell-cafe/2003-October/005231.html<br />
* An example of encoding existentials using RankTwoPolymorphism: http://haskell.org/pipermail/haskell-cafe/2003-October/005304.html<br />
* Another mailing list discussion (functional vs OO approaches): http://www.haskell.org/pipermail/haskell/2005-June/016058.html<br />
* Just another one: http://www.haskell.org/pipermail/haskell-cafe/2008-January/037950.html "type question again"<br />
* Haskell antipattern: Existential typeclass http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/<br />
<br />
=== Trac ===<br />
<br />
[http://hackage.haskell.org/trac/haskell-prime/wiki/ExistentialQuantification Existential Quantification] is a detailed material on the topic. It has link also to the smaller [http://hackage.haskell.org/trac/haskell-prime/wiki/ExistentialQuantifier Existential Quantifier] page.<br />
<br />
[[Category:Idioms]]<br />
[[Category:Glossary]]<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=61283Template Haskell2016-11-13T22:58:21Z<p>Ryantm: </p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|glasgow_exts|template-haskell|a Template Haskell section}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/tmp/notes2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [String]<br />
as = ["a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses syb to address some of the pain of dealing with the rather large data types. <br />
<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybes modName input = let<br />
<br />
rename :: GenericT<br />
rename = mkT $ \n -> if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
addMaybe :: GenericM Q<br />
addMaybe = mkM $ \(n :: Name, s :: Strict, ty :: Type) -> do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
in everywhere rename `fmap` everywhereM addMaybe input<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI d <- reify n<br />
addMaybes (nameModule n) d<br />
</haskell><br />
<br />
mkOptional then generates a new data type with all Names in that module with an added suffix _opt. Here is an example of its use:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
data Foo = Foo { a,b,c,d,e :: Double, f :: Int }<br />
<br />
mapM mkOptional [''Foo]<br />
</haskell><br />
<br />
Generates something like<br />
<haskell><br />
data Foo_opt = Foo_opt {a_opt :: Maybe Double, ..... f_opt :: Maybe Int}<br />
</haskell><br />
<br />
<br />
<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=61282Template Haskell2016-11-13T22:57:59Z<p>Ryantm: </p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|glasgow_exts|template-haskell|Template Haskell}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/tmp/notes2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [String]<br />
as = ["a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses syb to address some of the pain of dealing with the rather large data types. <br />
<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybes modName input = let<br />
<br />
rename :: GenericT<br />
rename = mkT $ \n -> if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
addMaybe :: GenericM Q<br />
addMaybe = mkM $ \(n :: Name, s :: Strict, ty :: Type) -> do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
in everywhere rename `fmap` everywhereM addMaybe input<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI d <- reify n<br />
addMaybes (nameModule n) d<br />
</haskell><br />
<br />
mkOptional then generates a new data type with all Names in that module with an added suffix _opt. Here is an example of its use:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
data Foo = Foo { a,b,c,d,e :: Double, f :: Int }<br />
<br />
mapM mkOptional [''Foo]<br />
</haskell><br />
<br />
Generates something like<br />
<haskell><br />
data Foo_opt = Foo_opt {a_opt :: Maybe Double, ..... f_opt :: Maybe Int}<br />
</haskell><br />
<br />
<br />
<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=61281Template Haskell2016-11-13T22:57:47Z<p>Ryantm: </p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuideT|glasgow_exts|template-haskell|Template Haskell}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/tmp/notes2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [String]<br />
as = ["a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses syb to address some of the pain of dealing with the rather large data types. <br />
<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybes modName input = let<br />
<br />
rename :: GenericT<br />
rename = mkT $ \n -> if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
addMaybe :: GenericM Q<br />
addMaybe = mkM $ \(n :: Name, s :: Strict, ty :: Type) -> do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
in everywhere rename `fmap` everywhereM addMaybe input<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI d <- reify n<br />
addMaybes (nameModule n) d<br />
</haskell><br />
<br />
mkOptional then generates a new data type with all Names in that module with an added suffix _opt. Here is an example of its use:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
data Foo = Foo { a,b,c,d,e :: Double, f :: Int }<br />
<br />
mapM mkOptional [''Foo]<br />
</haskell><br />
<br />
Generates something like<br />
<haskell><br />
data Foo_opt = Foo_opt {a_opt :: Maybe Double, ..... f_opt :: Maybe Int}<br />
</haskell><br />
<br />
<br />
<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Template:GHCUsersGuide&diff=61280Template:GHCUsersGuide2016-11-13T22:57:27Z<p>Ryantm: </p>
<hr />
<div>'''The [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ GHC Users Guide] has [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/{{{1}}}.html#{{{2}}} {{{3}}}].'''</div>Ryantmhttps://wiki.haskell.org/index.php?title=Rank-N_types&diff=61251Rank-N types2016-10-27T03:40:27Z<p>Ryantm: </p>
<hr />
<div>[[Category:Language extensions]]<br />
<br />
{{GHCUsersGuide|https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#arbitrary-rank-polymorphism an Arbitrary Rank Polymorphism section}}<br />
<br />
== About ==<br />
<br />
Normal Haskell '98 types are considered Rank-1 types. A Haskell '98 type signature such as<br />
<haskell>a -> b -> a</haskell><br />
implies that the type variables are universally quantified like so:<br />
<haskell>forall a b. a -> b -> a</haskell><br />
<hask>forall</hask> can be floated out of the right-hand side of <hask>-></hask> if it appears there, so:<br />
<haskell>forall a. a -> (forall b. b -> a)</haskell><br />
is also a Rank-1 type because it is equivalent to the previous signature.<br />
<br />
However, a <hask>forall</hask> appearing within the left-hand side of <hask>(->)</hask> cannot be moved up, and therefore forms another level or rank. The type is labeled "Rank-N" where N is the number of <hask>forall</hask>s which are nested and cannot be merged with a previous one. For example:<br />
<br />
<hask>(forall a. a -> a) -> (forall b. b -> b)</hask><br />
<br />
is a Rank-2 type because the latter <hask>forall</hask> can be moved to the start but the former one cannot. Therefore, there are two levels of universal quantification.<br />
<br />
Rank-N type reconstruction is undecidable in general, and some explicit type annotations are required in their presence.<br />
<br />
Rank-2 or Rank-N types may be specifically enabled by the language extensions<br />
<hask>{-# LANGUAGE Rank2Types #-}</hask> or <hask>{-# LANGUAGE RankNTypes #-}</hask>.<br />
<br />
== Church-encoded Lists ==<br />
Church-encoded lists use RankNTypes too, as seen in [http://stackoverflow.com/a/15593349/849891 a StackOverflow answer by sacundim]:<br />
<haskell> <br />
-- | Laws:<br />
--<br />
-- > runList xs cons nil == xs<br />
-- > runList (fromList xs) f z == foldr f z xs<br />
-- > foldr f z (toList xs) == runList xs f z<br />
newtype ChurchList a = <br />
ChurchList { runList :: forall r. (a -> r -> r) -> r -> r }<br />
<br />
-- | Make a 'ChurchList' out of a regular list.<br />
fromList :: [a] -> ChurchList a<br />
fromList xs = ChurchList $ \k z -> foldr k z xs<br />
<br />
-- | Turn a 'ChurchList' into a regular list.<br />
toList :: ChurchList a -> [a]<br />
toList xs = runList xs (:) []<br />
<br />
-- | The 'ChurchList' counterpart to '(:)'. Unlike 'DList', whose<br />
-- implementation uses the regular list type, 'ChurchList' abstracts<br />
-- over it as well.<br />
cons :: a -> ChurchList a -> ChurchList a<br />
cons x xs = ChurchList $ \k z -> k x (runList xs k z)<br />
<br />
-- | Append two 'ChurchList's. This runs in O(1) time. Note that<br />
-- there is no need to materialize the lists as @[a]@.<br />
append :: ChurchList a -> ChurchList a -> ChurchList a<br />
append xs ys = ChurchList $ \k z -> runList xs k (runList ys k z)<br />
<br />
-- i.e.,<br />
<br />
nil = {- fromList [] = ChurchList $ \k z -> foldr k z []<br />
= -} ChurchList $ \k z -> z<br />
<br />
singleton x = {- cons x nil = ChurchList $ \k z -> k x (runList nil k z) <br />
= -} ChurchList $ \k z -> k x z<br />
<br />
snoc xs x = {- append xs $ singleton x<br />
= ChurchList $ \k z -> runList xs k (runList (singleton x) k z) <br />
= -} ChurchList $ \k z -> runList xs k (k x z)<br />
</haskell><br />
<br />
== Relation to Existentials ==<br />
<br />
In order to unpack an existential type, you need a polymorphic function that works on any type that could be stored in the existential. This leads to a natural relation between higher-rank types and existentials; and an encoding of existentials in terms of higher rank types in continuation-passing style.<br />
<br />
In general, you can replace<br />
<haskell>data T a1 .. ai = forall t1 .. tj. constraints => Constructor e1 .. ek</haskell><br />
(where <hask>e1..ek</hask> are types in terms of <hask>a1..ai</hask> and <hask>t1..tj</hask>)<br />
<br />
<haskell>Constructor exp1 .. expk -- application of the constructor</haskell><br />
<br />
<haskell>case e of (Constructor pat1 .. patk) -> res</haskell><br />
<br />
with<br />
<br />
<haskell>data T' a1 .. ai = Constructor' (forall b. (forall t1..tj. constraints => e1 -> e2 -> ... -> ek -> b) -> b)</haskell><br />
<br />
<haskell>Constructor' (\f -> f exp1 .. expk)</haskell><br />
<br />
<haskell>case e of (Constructor' f) -> let k pat1 .. patk = res in f k</haskell><br />
<br />
== See also ==<br />
<br />
* [http://hackage.haskell.org/trac/haskell-prime/wiki/RankNTypes Rank-N types] on the Haskell' website.<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#arbitrary-rank-polymorphism The GHC User's Guide on higher-ranked polymorphism].</div>Ryantmhttps://wiki.haskell.org/index.php?title=Multi-parameter_type_class&diff=61250Multi-parameter type class2016-10-27T03:31:02Z<p>Ryantm: </p>
<hr />
<div>[[Category:Language extensions]]<br />
[[Category:Glossary]]<br />
[[Category:Stub articles]]<br />
<br />
{{GHCUsersGuide|https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#multi-parameter-type-classes a Multi Parameter Type Classes section}}<br />
<br />
== About ==<br />
<br />
Basically, [[type class|type classes]] which can take multiple arguments, such as:<br />
<br />
<haskell><br />
class Monad m => VarMonad m v where<br />
new :: a -> m (v a)<br />
get :: v a -> m a<br />
put :: v a -> a -> m ()<br />
<br />
instance VarMonad IO IORef where ...<br />
instance VarMonad (ST s) (STRef s) where ...<br />
</haskell><br />
<br />
To enable them, use the <hask>{-# LANGUAGE MultiParamTypeClasses #-}</hask> pragma.<br />
<br />
If you think of a single-parameter type class as a set of types, then a multi-parameter type class is a relation between types.<br />
<br />
Naive use of MPTCs may result in ambiguity, so [[functional dependencies]] were developed as a method of resolving that ambiguity, declaring that some subset of the parameters is sufficient to determine the values of the others.<br />
<br />
Some uses of MPTCs with functional dependencies can be replaced with [[type families]].<br />
<br />
The above example can even be implemented in<br />
[[Mutable variable|plain Haskell 98]].<br />
<br />
== Also see ==<br />
<br />
[http://hackage.haskell.org/trac/haskell-prime/wiki/MultiParamTypeClasses The Haskell' page]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Generalised_algebraic_datatype&diff=61249Generalised algebraic datatype2016-10-27T03:29:10Z<p>Ryantm: </p>
<hr />
<div>{{GHCUsersGuide|https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#generalised-algebraic-data-types-gadts a GADTs section}}<br />
<br />
== Papers ==<br />
<br />
See also [[Research papers/Type systems#Generalised Algebraic Data Types (GADTs)|research papers on type systems]].<br />
<br />
* A short description on generalised algebraic datatypes here [http://www.haskell.org/ghc/docs/latest/html/users_guide/data-type-extensions.html#gadt as GHC language features].<br />
* Another description with links on [http://hackage.haskell.org/trac/haskell-prime/wiki/GADTs Haskell' wiki].<br />
* [http://ecommons.library.cornell.edu/handle/1813/5614 First-Class Phantom Types] by James Cheney and Ralf Hinze<br />
* [http://cristal.inria.fr/~fpottier/publis/pottier-regis-gianas-05.pdf Stratified type inference for generalized algebraic data types] by François Pottier and Yann Régis-Gianas. It contains also a lot of links to other papers on GADTs.<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/papers/gadt/index.htm Simple unification-based type inference for GADTs] by Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, and Geoffrey Washburn. (Revised April 2006.)<br />
* [http://www.cs.mu.oz.au/~sulzmann/manuscript/simple-translate-gadts.ps Translating Generalized Algebraic Data Types to System F] written by [http://www.cs.mu.oz.au/~sulzmann/ Martin Sulzmann] and Meng Wang. [http://www.cs.mu.oz.au/~sulzmann/2005.html Many other papers]. The talk mentions also the notion of [[phantom type]], and [[existential type]], and [[type witness]].<br />
<br />
== Motivating example ==<br />
<br />
Generalised Algebraic Datatypes (GADTs) are datatypes for which a constructor has a non standard type. Indeed, in type systems incorporating GADTs, there are very few restrictions on the type that the data constructors can take. To show you how this could be useful, we will implement an evaluator for the typed SK calculus. Note that the K combinator is operationally similar to<br />
<math>\lambda\;x\;y\;.\;x</math><br />
and, similarly, S is similar to the combinator<br />
<math>\lambda\;x\;y\;z\;.\;x\;z\;(\;y\;z\;)</math><br />
which, in simply typed lambda calculus, have types<br />
<math>a \rightarrow b \rightarrow a </math><br />
and<br />
<math>(a \rightarrow b \rightarrow c) \rightarrow (a \rightarrow b) \rightarrow a \rightarrow c </math><br />
Without GADTs we would have to write something like this:<br />
<haskell><br />
data Term = K | S | Term :@ Term <br />
infixl 6 :@<br />
</haskell><br />
With GADTs, however, we can have the terms carry around more type information and create more interesting terms, like so:<br />
<haskell><br />
data Term x where<br />
K :: Term (a -> b -> a)<br />
S :: Term ((a -> b -> c) -> (a -> b) -> a -> c)<br />
Const :: a -> Term a<br />
(:@) :: Term (a -> b) -> (Term a) -> Term b<br />
infixl 6 :@<br />
</haskell><br />
now we can write a small step evaluator:<br />
<haskell><br />
eval::Term a -> Term a<br />
eval (K :@ x :@ y) = x<br />
eval (S :@ x :@ y :@ z) = x :@ z :@ (y :@ z)<br />
eval x = x<br />
</haskell><br />
Since the types of the so-called object language, being the typed SK calculus, are mimicked by the type system in our meta language, being Haskell, we have a pretty convincing argument that the evaluator won't mangle our types. We say that typing is preserved under evaluation (preservation.) Note that this is an argument and not a proof.<br />
<br />
This, however, comes at a price: let's see what happens when you try to convert strings into our object language:<br />
<haskell><br />
parse "K" = K<br />
parse "S" = S<br />
</haskell><br />
you'll get a nasty error like so:<br />
<br />
Occurs check: cannot construct the infinite type: c = b -> c<br />
Expected type: Term ((a -> b -> c) -> (a -> b) -> a -> b -> c)<br />
Inferred type: Term ((a -> b -> c) -> (a -> b) -> a -> c)<br />
In the definition of `foo': foo "S" = S<br />
<br />
One could, however, reason that parse has type: <hask>String -> exists a. Term a</hask>, see also [[Existential type]].<br />
<br />
== Example with lists ==<br />
<br />
here's another, smaller example:<br />
<haskell><br />
data Empty<br />
data NonEmpty<br />
data List x y where<br />
Nil :: List a Empty<br />
Cons:: a -> List a b -> List a NonEmpty<br />
<br />
safeHead:: List x NonEmpty -> x<br />
safeHead (Cons a b) = a<br />
</haskell><br />
<br />
now safeHead can only be applied to non empty lists, and will never evaluate to bottom. This too comes at a cost; consider the function:<br />
<br />
<haskell><br />
silly 0 = Nil<br />
silly 1 = Cons 1 Nil<br />
</haskell><br />
<br />
yields an objection from ghc:<br />
Couldn't match `Empty' against `NonEmpty'<br />
Expected type: List a Empty<br />
Inferred type: List a NonEmpty<br />
In the application `Cons 1 Nil'<br />
In the definition of `silly': silly 1 = Cons 1 Nil<br />
<br />
== Parsing Example ==<br />
<br />
Note that GADTs provide a rather nice platform for embedded domain specific languages. In particular, they allow an [[EDSL]] to use Haskell's type system for its own purposes. As a simple example, we might have an EDSL for simple (regexp-like) parsers that looks something like:<br />
<br />
<haskell><br />
data Parser tok a where<br />
Zero :: Parser tok ()<br />
One :: Parser tok ()<br />
Check :: (tok -> Bool) -> Parser tok tok<br />
Satisfy :: ([tok] -> Bool) -> Parser tok [tok]<br />
Push :: tok -> Parser tok a -> Parser tok a<br />
Plus :: Parser tok a -> Parser tok b -> Parser tok (Either a b)<br />
Times :: Parser tok a -> Parser tok b -> Parser tok (a,b)<br />
Star :: Parser tok a -> Parser tok [a]<br />
</haskell><br />
<br />
An evaluator/parser is then straightforward. Below it's written monadically for<br />
convenience, but this also means that we could generalise the return type to being in any MonadPlus. Note that an advantage of this representation which we don't show here is that we could also write a function which applies algebraic rules to the structure to try to simplify the parser before running it. (Though if we were really concerned with efficiency, we'd probably also need a couple more primitives.)<br />
<br />
<haskell><br />
parse :: Parser tok a -> [tok] -> Maybe a<br />
<br />
-- Zero always fails.<br />
parse Zero ts = mzero<br />
<br />
-- One matches only the empty string.<br />
parse One [] = return ()<br />
parse One _ = mzero<br />
<br />
-- Check p matches a string with exactly one token t such that p t holds.<br />
parse (Check p) [t] = if p t then return t else mzero<br />
parse (Check p) _ = mzero<br />
<br />
-- Satisfy p any string such that p ts holds.<br />
parse (Satisfy p) xs = if p xs then return xs else mzero<br />
<br />
-- Push t x matches a string ts when x matches (t:ts).<br />
parse (Push t x) ts = parse x (t:ts)<br />
<br />
-- Plus x y matches when either x or y does.<br />
parse (Plus x y) ts = liftM Left (parse x ts) `mplus` liftM Right (parse y ts)<br />
<br />
-- Times x y matches the concatenation of x and y.<br />
parse (Times x y) [] = liftM2 (,) (parse x []) (parse y [])<br />
parse (Times x y) (t:ts) = <br />
parse (Times (Push t x) y) ts `mplus`<br />
liftM2 (,) (parse x []) (parse y (t:ts))<br />
<br />
-- Star x matches zero or more copies of x.<br />
parse (Star x) [] = return []<br />
parse (Star x) (t:ts) = do<br />
(v,vs) <- parse (Times x (Star x)) (t:ts)<br />
return (v:vs)<br />
</haskell><br />
<br />
Finally, we might define some examples:<br />
<br />
<haskell><br />
token x = Check (== x)<br />
string xs = Satisfy (== xs)<br />
<br />
p = Times (token 'a') (token 'b')<br />
p1 = Times (Star (token 'a')) (Star (token 'b'))<br />
p2 = Star p1<br />
<br />
blocks :: (Eq tok) => Parser tok [[tok]]<br />
blocks = Star (Satisfy allEqual)<br />
where allEqual xs = and (zipWith (==) xs (drop 1 xs))<br />
<br />
evenOdd = Plus (Star (Times (Check even) (Check odd)))<br />
(Star (Times (Check odd) (Check even)))<br />
<br />
</haskell><br />
<br />
Testing this in ghci:<br />
<pre><br />
*Main> parse p "ab"<br />
Just ('a','b')<br />
*Main> parse p "ac"<br />
Nothing<br />
*Main> parse p1 "aaabbbb"<br />
Just ("aaa","bbbb")<br />
*Main> parse p2 "aaabbbbaabbbbbbbaaabbabab"<br />
Just [("aaa","bbbb"),("aa","bbbbbbb"),("aaa","bb"),("a","b"),("a","b")]<br />
*Main> :t p2<br />
p2 :: Parser Char [([Char], [Char])]<br />
*Main> parse blocks "aaaabbbbbbbbcccccddd"<br />
Just ["aaaa","bbbbbbbb","ccccc","ddd"]<br />
*Main> parse evenOdd [0..9]<br />
Just (Left [(0,1),(2,3),(4,5),(6,7),(8,9)])<br />
*Main> parse evenOdd [1..10]<br />
Just (Right [(1,2),(3,4),(5,6),(7,8),(9,10)])<br />
<br />
</pre><br />
<br />
== Projects containing GADTs ==<br />
<br />
Papers on [[Libraries and tools/Database interfaces/HaskellDB|HaskellDB]] describe problems when GADTs can help (but HaskellDB solves these problems with [[phantom type]]s).<br />
<br />
[[Darcs]] represents motivating examples for GADTs, too -- and uses them.<br />
The motivations are described in David Roundy's FOSDEM slides ([http://physics.oregonstate.edu/~roundyd/talks/fosdem-2006.pdf Implementing the Darcs Patch Formalism and Verifying It]) (see p. 11, 13--14.). The talk mentions also the notions of [[phantom type]], and [[existential type]], and [[type witness]] (see p. 15).<br />
<br />
== See also ==<br />
<br />
* [[Algebraic data type]]<br />
* [[GADTs for dummies]]<br />
* [http://en.wikibooks.org/wiki/Haskell/GADT The Haskell Wikibook section about GADT]<br />
* [http://apfelmus.nfshost.com/blog/2010/06/01-gadts-video.html A video that explains GADTs]<br />
<br />
<br />
[[Category:Glossary]]<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Functional_dependencies&diff=61248Functional dependencies2016-10-27T03:27:21Z<p>Ryantm: </p>
<hr />
<div>[[Category:Glossary]]<br />
[[Category:Language extensions]]<br />
Functional dependencies are used to constrain the parameters of type classes. They let you state that in a [[multi-parameter type class]], one of the [[parameter]]s can be determined from the others, so that the [[parameter]] determined by the others can, for example, be the return type but none of the argument types of some of the methods.<br />
<br />
{{GHCUsersGuide|https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#functional-dependencies a Functional Dependencies section}}<br />
<br />
==Examples==<br />
Suppose you want to implement some code to perform simple [[linear algebra]]:<br />
<haskell><br />
data Vector = Vector Int Int deriving (Eq, Show)<br />
data Matrix = Matrix Vector Vector deriving (Eq, Show)<br />
</haskell><br />
You want these to behave as much like numbers as possible. So you might start by overloading Haskell's Num class:<br />
<haskell><br />
instance Num Vector where<br />
Vector a1 b1 + Vector a2 b2 = Vector (a1+a2) (b1+b2)<br />
Vector a1 b1 - Vector a2 b2 = Vector (a1-a2) (b1-b2)<br />
{- ... and so on ... -}<br />
<br />
instance Num Matrix where<br />
Matrix a1 b1 + Matrix a2 b2 = Matrix (a1+a2) (b1+b2)<br />
Matrix a1 b1 - Matrix a2 b2 = Matrix (a1-a2) (b1-b2)<br />
{- ... and so on ... -}<br />
</haskell><br />
The problem comes when you want to start multiplying quantities. You really need a multiplication function which overloads to different types:<br />
<haskell><br />
(*) :: Matrix -> Matrix -> Matrix<br />
(*) :: Matrix -> Vector -> Vector<br />
(*) :: Matrix -> Int -> Matrix<br />
(*) :: Int -> Matrix -> Matrix<br />
{- ... and so on ... -}<br />
</haskell><br />
How do we specify a type class which allows all these possibilities?<br />
<br />
We could try this:<br />
<haskell><br />
class Mult a b c where<br />
(*) :: a -> b -> c<br />
<br />
instance Mult Matrix Matrix Matrix where<br />
{- ... -}<br />
<br />
instance Mult Matrix Vector Vector where<br />
{- ... -}<br />
</haskell><br />
That, however, isn't really what we want. As it stands, even a simple expression like this has an ambiguous type unless you supply an additional type declaration on the intermediate expression:<br />
<haskell><br />
m1, m2, m3 :: Matrix<br />
(m1 * m2) * m3 -- type error; type of (m1*m2) is ambiguous<br />
(m1 * m2) :: Matrix * m3 -- this is ok<br />
</haskell><br />
After all, nothing is stopping someone from coming along later and adding another instance:<br />
<haskell><br />
instance Mult Matrix Matrix (Maybe Char) where<br />
{- whatever -}<br />
</haskell><br />
The problem is that <hask>c</hask> shouldn't really be a free type variable. When you know the types of the things that you're multiplying, the result type should be determined from that information alone.<br />
<br />
You can express this by specifying a functional dependency, or fundep for short:<br />
<haskell><br />
class Mult a b c | a b -> c where<br />
(*) :: a -> b -> c<br />
</haskell><br />
This tells Haskell that <hask>c</hask> is uniquely determined from <hask>a</hask> and <hask>b</hask>.<br />
<br />
Fundeps have lots more uses than just implementing C++-style function overloading, of course. See [http://web.cecs.pdx.edu/~mpj/pubs/fundeps.html the paper] by Mark P. Jones for further details.<br />
<br />
Fundeps are not standard Haskell 98. (Nor are [[multi-parameter type class]]es, for that matter.) They are, however, supported at least in [[GHC]] and [[Hugs]] and will almost certainly end up in Haskell'.<br />
<br />
[[User:AndrewBromage]]<br />
<br />
== Another example ==<br />
<br />
The following example makes use of the FlexibleInstances, MultiParamTypeClasses and FunctionalDependencies GHC extensions.<br />
<br />
<haskell><br />
-- Read as: "container" type determines "elem" type.<br />
class Extract container elem | container -> elem where<br />
extract :: container -> elem<br />
</haskell><br />
<br />
The functional dependency "container -> elem" promises that we won't declare multiple instances with the same "container" type.<br />
<br />
<haskell><br />
instance Extract (a,b) a where<br />
extract (x,_) = x<br />
</haskell><br />
<br />
Because of the functional dependency we can't have the previous instance *and* this one:<br />
<br />
<haskell>-- instance Extract (a,b) b where ...</haskell><br />
<br />
Because of the functional dependency we can say:<br />
<br />
<haskell>v = extract ('x', 3)</haskell><br />
<br />
and it will infer the type <haskell>v :: Char</haskell><br />
<br />
Without the functional dependency, both instances above would be allowed, and the type of v would be potentially ambiguous. Even if only one instance is defined, the type system will not figure it out without the functional dependency.<br />
<br />
== Tutorials ==<br />
<br />
* [http://www.cs.chalmers.se/~hallgren/Papers/wm01.html Fun with functional dependencies], Thomas Hallgren (2001)<br />
* [[User:ConradParker/InstantInsanity | Type-Level Instant Insanity]], Conrad Parker (2007)<br />
<br />
== See also ==<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#functional-dependencies GHC documentation]<br />
* [[Functional dependencies vs. type families]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Existential_type&diff=61247Existential type2016-10-27T03:26:56Z<p>Ryantm: </p>
<hr />
<div>__TOC__<br />
This is an extension of Haskell available in [[GHC]]. <br />
<br />
{{GHCUsersGuide|https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#existentially-quantified-data-constructors an Existential Quantification section}}<br />
<br />
==Introduction to existential types==<br />
<br />
=== Overview ===<br />
<br />
Normally when creating a new type using <hask>type</hask>, <hask>newtype</hask>, <hask>data</hask>, etc., every type variable that appears on the right-hand side must also appear on the left-hand side. Existential types are a way of turning this off.<br />
<br />
=== Basics ===<br />
<br />
Existential types can be ''used'' for several different purposes. But what they ''do'' is to 'hide' a type variable on the right-hand side.<br />
<br />
Normally, any type variable appearing on the right must also appear on the left:<br />
<br />
<haskell><br />
data Worker x y = Worker {buffer :: b, input :: x, output :: y}<br />
</haskell><br />
<br />
This is an error, since the type of the buffer isn't specified on the right (it's a type variable rather than a type) but also isn't specified on the left (there's no 'b' in the left part). In Haskell98, you would have to write<br />
<br />
<haskell><br />
data Worker b x y = Worker {buffer :: b, input :: x, output :: y}<br />
</haskell><br />
<br />
That may or may not be an actual problem.<br />
<br />
Usually there is no problem at all with this state of affairs (which is why Haskell98 works this way). However, suppose that a <hask>Worker</hask> can use ''any'' type 'b' so long as it belongs to some particular class. Then every function that uses a <hask>Worker</hask> will have a type like<br />
<br />
<haskell><br />
foo :: (Buffer b) => Worker b Int Int<br />
</haskell><br />
<br />
or something. (In particular, failing to write an explicit type signature will invoke the dreaded [[monomorphism restriction]].) Using existential types, we can avoid this:<br />
<br />
<haskell><br />
data Worker x y = forall b. Buffer b => Worker {buffer :: b, input :: x, output :: y}<br />
<br />
foo :: Worker Int Int<br />
</haskell><br />
<br />
The type of the buffer now does ''not'' appear in the <hask>Worker</hask> type at all.<br />
<br />
This has a number of consequences. First of all, it is now impossible for a function to demand a <hask>Worker</hask> having a specific type of buffer. Second, the type of <hask>foo</hask> can now be derived automatically without needing an explicit type signature. (No [[monomorphism restriction]].) Thirdly, since code now has ''no idea'' what type the <hask>buffer</hask> function returns, you are more limited in what you can do to it.<br />
<br />
In general, when you use a 'hidden' type in this way, you will usually want that type to belong to a specific class, or you will want to pass some functions along that can work on that type. Otherwise you'll have some value belonging to a random unknown type, and you won't be able to ''do'' anything to it!<br />
<br />
Note: You can use existential types to convert a more specific type into a less specific one. (See the examples below.) There is ''no way'' to perform the reverse conversion!<br />
<br />
== Examples ==<br />
<br />
===A short example===<br />
<br />
This illustrates creating a heterogeneous list, all of whose members implement "Show", and progressing through that list to show these items:<br />
<br />
<haskell><br />
data Obj = forall a. (Show a) => Obj a<br />
<br />
xs :: [Obj]<br />
xs = [Obj 1, Obj "foo", Obj 'c']<br />
<br />
doShow :: [Obj] -> String<br />
doShow [] = ""<br />
doShow ((Obj x):xs) = show x ++ doShow xs<br />
</haskell><br />
<br />
With output: <code>doShow xs ==> "1\"foo\"'c'"</code><br />
<br />
===Expanded example - rendering objects in a raytracer===<br />
<br />
====Problem statement====<br />
<br />
In a raytracer, a requirement is to be able to render several different objects (like a ball, mesh or whatever). The first step is a type class for Renderable like so:<br />
<br />
<haskell><br />
class Renderable a where<br />
boundingSphere :: a -> Sphere<br />
hit :: a -> [Fragment] -- returns the "fragments" of all hits with ray<br />
{- ... etc ... -}<br />
</haskell><br />
<br />
To solve the problem, the <hask>hit</hask> function must apply to several objects (like a sphere and a polygon for instance).<br />
<br />
<haskell><br />
hits :: Renderable a => [a] -> [Fragment]<br />
hits xs = sortByDistance $ concatMap hit xs<br />
</haskell><br />
<br />
However, this does not work as written since the elements of the list can be of '''SEVERAL''' different types (like a sphere and a polygon and a mesh etc. etc.) but<br />
lists need to have elements of the same type.<br />
<br />
====The solution====<br />
<br />
Use 'existential types' - an extension to Haskell that can be found in most compilers.<br />
<br />
The following example is based on GHC :<br />
<br />
<haskell><br />
{-# OPTIONS -fglasgow-exts #-}<br />
<br />
{- ...-}<br />
<br />
data AnyRenderable = forall a. Renderable a => AnyRenderable a<br />
<br />
instance Renderable AnyRenderable where<br />
boundingSphere (AnyRenderable a) = boundingSphere a<br />
hit (AnyRenderable a) = hit a<br />
{- ... -}<br />
</haskell><br />
<br />
Now, create lists with type <hask>[AnyRenderable]</hask>, for example,<br />
<haskell><br />
[ AnyRenderable x<br />
, AnyRenderable y<br />
, AnyRenderable z ]<br />
</haskell><br />
where x, y, z can be from different instances of <hask>Renderable</hask>.<br />
=== Dynamic dispatch mechanism of OOP ===<br />
<br />
'''Existential types''' in conjunction with type classes can be used to emulate the dynamic dispatch mechanism of object oriented programming languages. To illustrate this concept I show how a classic example from object oriented programming can be encoded in Haskell.<br />
<br />
<haskell><br />
class Shape_ a where<br />
perimeter :: a -> Double<br />
area :: a -> Double<br />
<br />
data Shape = forall a. Shape_ a => Shape a<br />
<br />
type Radius = Double<br />
type Side = Double<br />
<br />
data Circle = Circle Radius<br />
data Rectangle = Rectangle Side Side<br />
data Square = Square Side<br />
<br />
<br />
instance Shape_ Circle where<br />
perimeter (Circle r) = 2 * pi * r<br />
area (Circle r) = pi * r * r<br />
<br />
instance Shape_ Rectangle where<br />
perimeter (Rectangle x y) = 2*(x + y)<br />
area (Rectangle x y) = x * y<br />
<br />
instance Shape_ Square where<br />
perimeter (Square s) = 4*s<br />
area (Square s) = s*s<br />
<br />
instance Shape_ Shape where<br />
perimeter (Shape shape) = perimeter shape<br />
area (Shape shape) = area shape<br />
<br />
<br />
--<br />
-- Smart constructor<br />
--<br />
<br />
circle :: Radius -> Shape<br />
circle r = Shape (Circle r)<br />
<br />
rectangle :: Side -> Side -> Shape<br />
rectangle x y = Shape (Rectangle x y)<br />
<br />
square :: Side -> Shape<br />
square s = Shape (Square s)<br />
<br />
shapes :: [Shape]<br />
shapes = [circle 2.4, rectangle 3.1 4.4, square 2.1]<br />
</haskell><br />
<br />
(You may see other [[Smart constructors]] for other purposes).<br />
<br />
=== [[Generalised algebraic datatype]] ===<br />
<br />
The type of the <hask>parse</hask> function for [[Generalised algebraic datatype#Motivating example|this GADT]] is a good example to illustrate the concept of existential type.<br />
<br />
=== SomeException ===<br />
<hask>Control.Exception</hask> (see [http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Exception.html documentation]) provides extensible exceptions by making the core exception type, <hask>SomeException</hask>, an existential:<br />
<br />
<haskell><br />
class (Show e, Typeable e) => Exception e where<br />
toException :: e -> SomeException<br />
fromException :: SomeException -> Maybe e<br />
data SomeException = forall a. Exception a => SomeException a<br />
</haskell><br />
<br />
You can define your own exceptions by making them an instance of the <hask>Exception</hask> class. Then there are two basic ways of dealing with exceptions:<br />
#If you have a <hask>SomeException</hask> value, use <hask>fromException</hask>. This returns <hask>Just e</hask> if the exception is the type you want. If it's something else, you get <hask>Nothing</hask>. You could check multiple types using a guard. This is what you'll have to use if you're dealing with <hask>SomeException</hask>s in pure code.<br />
#If you're in IO and have an expression that might throw an exception, <hask>catch</hask> lets you catch it. (There's also a version generalised to other instances of <hask>MonadIO</hask> in the <hask>lifted-base</hask> package). Its second argument takes a handler, which is a function accepting an exception of the type you want. If the first argument throws an exception, <hask>catch</hask> uses the <hask>Typeable</hask> library's typesafe cast to try to convert it to the type you want, then (if it succeeded) passes it to the handler. You can apply <hask>catch</hask> many times to the same expression with handlers for different exception types.<br />
#Even if <hask>fromException</hask> doesn't turn up an exception type you know, and <hask>catch</hask> doesn't catch an exception type you know, you can still <hask>show</hask> the unknown exception, maybe after catching <hask>SomeException</hask>.<br />
<br />
==Alternate methods==<br />
===Concrete data types===<br />
====Universal instance of a Class====<br />
Here one way to simulate existentials (Hawiki note: (Borrowed from somewhere...))<br />
<br />
<br />
Suppose I have a type class Shape a<br />
<haskell><br />
type Point = (Float,Float)<br />
<br />
class Shape a where<br />
draw :: a -> IO ()<br />
translate :: a-> Point -> a<br />
<br />
</haskell><br />
<br />
Then we can pack shapes up into a [[concrete data type]] like this:<br />
<haskell><br />
data SHAPE = SHAPE (IO ()) (Point -> SHAPE)<br />
</haskell><br />
with a function like this<br />
<haskell><br />
packShape :: Shape a => a -> SHAPE<br />
packShape s = SHAPE (draw s) (\(x,y) -> packShape (translate s (x,y)))<br />
</haskell><br />
This would be useful if we needed a list of shapes that we would need to translate and draw.<br />
<br />
In fact we can make <hask>SHAPE</hask> an instance of <hask>Shape</hask>:<br />
<haskell><br />
instance Shape SHAPE where<br />
draw (SHAPE d t) = d<br />
translate (SHAPE d t) = t<br />
</haskell><br />
<br />
So SHAPE is a sort of universal instance.<br />
<br />
====Using constructors and combinators====<br />
Why bother with class <hask>Shape</hask>? Why not just go straight to<br />
<br />
<haskell><br />
data Shape = Shape {<br />
draw :: IO()<br />
translate :: (Int, Int) -> Shape<br />
}<br />
</haskell><br />
<br />
Then you can create a library of shape [[constructor]]s and [[combinator]]s<br />
that each have defined "draw" and "translate" in their "where" clauses.<br />
<br />
<haskell><br />
circle :: (Int, Int) -> Int -> Shape<br />
circle (x,y) r =<br />
Shape draw1 translate1<br />
where<br />
draw1 = ...<br />
translate1 (x1,y1) = circle (x+x1, y+y1) r<br />
<br />
shapeGroup :: [Shape] -> Shape<br />
shapeGroup shapes = Shape draw1 translate1<br />
where<br />
draw1 = mapM_ draw shapes<br />
translate1 v = shapeGroup $ map (translate v) shapes<br />
</haskell><br />
<br />
===Cases that really require existentials===<br />
<br />
There are cases where this sort of trick doesn't work. Here are two examples from a haskell mailing list discussion (from K. Claussen) that don't seem expressible without<br />
existentials. (But maybe one can rethink the whole thing :)<br />
<haskell><br />
data Expr a = Val a | forall b . Apply (Expr (b -> a)) (Expr b)<br />
</haskell><br />
and<br />
<haskell><br />
data Action = forall b . Act (IORef b) (b -> IO ())<br />
</haskell><br />
(Maybe this last one could be done as a <hask>type Act (IORef b) (IORef b -> IO ())</hask> then we could hide the <hask>IORef</hask> as above, that is go ahead and apply the second argument to the first)<br />
<br />
=== Existentials in terms of "forall" ===<br />
It is also possible to express existentials as type expressions directly (without a <hask>data</hask> declaration) with RankNTypes. Taking the above example:<br />
<br />
<haskell>data Obj = forall a. (Show a) => Obj a</haskell><br />
<br />
the type <hask>Obj</hask> is equivalent to:<br />
<br />
<haskell>forall r. (forall a. Show a => a -> r) -> r</haskell><br />
<br />
(the leading <hask>forall r.</hask> is optional unless the expression is part of another expression). The conversions are:<br />
<br />
<haskell><br />
fromObj :: Obj <br />
-> forall r. (forall a. Show a => a -> r) -> r<br />
fromObj (Obj x) k = k x<br />
<br />
toObj :: (forall r. (forall a. Show a => a -> r) -> r) <br />
-> Obj<br />
toObj f = f Obj<br />
</haskell><br />
<br />
== Examples from the [http://www.cs.uu.nl/wiki/Ehc/ Essential Haskell Compiler] project ==<br />
<br />
See the [http://www.cs.uu.nl/wiki/Ehc/#On_EHC documentation on EHC], each paper at the ''Version 4'' part:<br />
* Chapter 8 (EH4) of Atze Dijkstra's [http://www.cs.uu.nl/groups/ST/Projects/ehc/ehc-book.pdf Essential Haskell PhD thesis] (most recent version). A detailed explanation. It explains also that existential types can be expressed in Haskell, but their use is restricted to data declarations, and the notation (using keyword <hask>forall</hask>) may be confusing. In Essential Haskell, existential types can occur not only in data declarations, and a separate keyword <hask>exists</hask> is used for their notation.<br />
* [http://www.cs.uu.nl/wiki/pub/Ehc/WebHome/20050107-eh-intro.pdf Essential Haskell Compiler overview]<br />
* [http://www.cs.uu.nl/wiki/Ehc/Examples#EH_4_forall_and_exists_everywher Examples]<br />
<br />
==See also==<br />
* A mailinglist discussion: http://haskell.org/pipermail/haskell-cafe/2003-October/005231.html<br />
* An example of encoding existentials using RankTwoPolymorphism: http://haskell.org/pipermail/haskell-cafe/2003-October/005304.html<br />
* Another mailing list discussion (functional vs OO approaches): http://www.haskell.org/pipermail/haskell/2005-June/016058.html<br />
* Just another one: http://www.haskell.org/pipermail/haskell-cafe/2008-January/037950.html "type question again"<br />
* Haskell antipattern: Existential typeclass http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/<br />
<br />
=== Trac ===<br />
<br />
[http://hackage.haskell.org/trac/haskell-prime/wiki/ExistentialQuantification Existential Quantification] is a detailed material on the topic. It has link also to the smaller [http://hackage.haskell.org/trac/haskell-prime/wiki/ExistentialQuantifier Existential Quantifier] page.<br />
<br />
[[Category:Idioms]]<br />
[[Category:Glossary]]<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Template:GHCUsersGuide&diff=61246Template:GHCUsersGuide2016-10-27T03:26:31Z<p>Ryantm: </p>
<hr />
<div>'''The [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ GHC Users Guide] has [{{{1}}}].'''</div>Ryantmhttps://wiki.haskell.org/index.php?title=Implicit_parameters&diff=61245Implicit parameters2016-10-27T03:25:53Z<p>Ryantm: </p>
<hr />
<div>{{GHCUsersGuide|https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#implicit-parameters Implicit Parameters section}}<br />
<br />
Working example:<br />
<br />
{-# LANGUAGE ImplicitParams #-}<br />
<br />
import Data.List (sortBy)<br />
<br />
sortBy' :: (?cmp :: a -> a -> Ordering) => [a] -> [a]<br />
sortBy' = sortBy ?cmp<br />
<br />
sort :: Ord a => [a] -> [a]<br />
sort = let ?cmp = compare in sortBy'<br />
<br />
main = putStrLn (show (sort [3,1,2]))<br />
<br />
[[Category:Language extensions]]<br />
[[Category:GHC]]<br />
[[Category:Stub articles]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Functional_dependencies&diff=61244Functional dependencies2016-10-27T03:13:50Z<p>Ryantm: </p>
<hr />
<div>[[Category:Glossary]]<br />
[[Category:Language extensions]]<br />
Functional dependencies are used to constrain the parameters of type classes. They let you state that in a [[multi-parameter type class]], one of the [[parameter]]s can be determined from the others, so that the [[parameter]] determined by the others can, for example, be the return type but none of the argument types of some of the methods.<br />
<br />
{{GHCUsersGuide|https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#functional-dependencies Functional Dependencies section}}<br />
<br />
==Examples==<br />
Suppose you want to implement some code to perform simple [[linear algebra]]:<br />
<haskell><br />
data Vector = Vector Int Int deriving (Eq, Show)<br />
data Matrix = Matrix Vector Vector deriving (Eq, Show)<br />
</haskell><br />
You want these to behave as much like numbers as possible. So you might start by overloading Haskell's Num class:<br />
<haskell><br />
instance Num Vector where<br />
Vector a1 b1 + Vector a2 b2 = Vector (a1+a2) (b1+b2)<br />
Vector a1 b1 - Vector a2 b2 = Vector (a1-a2) (b1-b2)<br />
{- ... and so on ... -}<br />
<br />
instance Num Matrix where<br />
Matrix a1 b1 + Matrix a2 b2 = Matrix (a1+a2) (b1+b2)<br />
Matrix a1 b1 - Matrix a2 b2 = Matrix (a1-a2) (b1-b2)<br />
{- ... and so on ... -}<br />
</haskell><br />
The problem comes when you want to start multiplying quantities. You really need a multiplication function which overloads to different types:<br />
<haskell><br />
(*) :: Matrix -> Matrix -> Matrix<br />
(*) :: Matrix -> Vector -> Vector<br />
(*) :: Matrix -> Int -> Matrix<br />
(*) :: Int -> Matrix -> Matrix<br />
{- ... and so on ... -}<br />
</haskell><br />
How do we specify a type class which allows all these possibilities?<br />
<br />
We could try this:<br />
<haskell><br />
class Mult a b c where<br />
(*) :: a -> b -> c<br />
<br />
instance Mult Matrix Matrix Matrix where<br />
{- ... -}<br />
<br />
instance Mult Matrix Vector Vector where<br />
{- ... -}<br />
</haskell><br />
That, however, isn't really what we want. As it stands, even a simple expression like this has an ambiguous type unless you supply an additional type declaration on the intermediate expression:<br />
<haskell><br />
m1, m2, m3 :: Matrix<br />
(m1 * m2) * m3 -- type error; type of (m1*m2) is ambiguous<br />
(m1 * m2) :: Matrix * m3 -- this is ok<br />
</haskell><br />
After all, nothing is stopping someone from coming along later and adding another instance:<br />
<haskell><br />
instance Mult Matrix Matrix (Maybe Char) where<br />
{- whatever -}<br />
</haskell><br />
The problem is that <hask>c</hask> shouldn't really be a free type variable. When you know the types of the things that you're multiplying, the result type should be determined from that information alone.<br />
<br />
You can express this by specifying a functional dependency, or fundep for short:<br />
<haskell><br />
class Mult a b c | a b -> c where<br />
(*) :: a -> b -> c<br />
</haskell><br />
This tells Haskell that <hask>c</hask> is uniquely determined from <hask>a</hask> and <hask>b</hask>.<br />
<br />
Fundeps have lots more uses than just implementing C++-style function overloading, of course. See [http://web.cecs.pdx.edu/~mpj/pubs/fundeps.html the paper] by Mark P. Jones for further details.<br />
<br />
Fundeps are not standard Haskell 98. (Nor are [[multi-parameter type class]]es, for that matter.) They are, however, supported at least in [[GHC]] and [[Hugs]] and will almost certainly end up in Haskell'.<br />
<br />
[[User:AndrewBromage]]<br />
<br />
== Another example ==<br />
<br />
The following example makes use of the FlexibleInstances, MultiParamTypeClasses and FunctionalDependencies GHC extensions.<br />
<br />
<haskell><br />
-- Read as: "container" type determines "elem" type.<br />
class Extract container elem | container -> elem where<br />
extract :: container -> elem<br />
</haskell><br />
<br />
The functional dependency "container -> elem" promises that we won't declare multiple instances with the same "container" type.<br />
<br />
<haskell><br />
instance Extract (a,b) a where<br />
extract (x,_) = x<br />
</haskell><br />
<br />
Because of the functional dependency we can't have the previous instance *and* this one:<br />
<br />
<haskell>-- instance Extract (a,b) b where ...</haskell><br />
<br />
Because of the functional dependency we can say:<br />
<br />
<haskell>v = extract ('x', 3)</haskell><br />
<br />
and it will infer the type <haskell>v :: Char</haskell><br />
<br />
Without the functional dependency, both instances above would be allowed, and the type of v would be potentially ambiguous. Even if only one instance is defined, the type system will not figure it out without the functional dependency.<br />
<br />
== Tutorials ==<br />
<br />
* [http://www.cs.chalmers.se/~hallgren/Papers/wm01.html Fun with functional dependencies], Thomas Hallgren (2001)<br />
* [[User:ConradParker/InstantInsanity | Type-Level Instant Insanity]], Conrad Parker (2007)<br />
<br />
== See also ==<br />
* [http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#functional-dependencies GHC documentation]<br />
* [[Functional dependencies vs. type families]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Existential_type&diff=61243Existential type2016-10-27T03:12:14Z<p>Ryantm: </p>
<hr />
<div>__TOC__<br />
This is an extension of Haskell available in [[GHC]]. <br />
<br />
{{GHCUsersGuide|https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#existentially-quantified-data-constructors Existential Quantification section}}<br />
<br />
==Introduction to existential types==<br />
<br />
=== Overview ===<br />
<br />
Normally when creating a new type using <hask>type</hask>, <hask>newtype</hask>, <hask>data</hask>, etc., every type variable that appears on the right-hand side must also appear on the left-hand side. Existential types are a way of turning this off.<br />
<br />
=== Basics ===<br />
<br />
Existential types can be ''used'' for several different purposes. But what they ''do'' is to 'hide' a type variable on the right-hand side.<br />
<br />
Normally, any type variable appearing on the right must also appear on the left:<br />
<br />
<haskell><br />
data Worker x y = Worker {buffer :: b, input :: x, output :: y}<br />
</haskell><br />
<br />
This is an error, since the type of the buffer isn't specified on the right (it's a type variable rather than a type) but also isn't specified on the left (there's no 'b' in the left part). In Haskell98, you would have to write<br />
<br />
<haskell><br />
data Worker b x y = Worker {buffer :: b, input :: x, output :: y}<br />
</haskell><br />
<br />
That may or may not be an actual problem.<br />
<br />
Usually there is no problem at all with this state of affairs (which is why Haskell98 works this way). However, suppose that a <hask>Worker</hask> can use ''any'' type 'b' so long as it belongs to some particular class. Then every function that uses a <hask>Worker</hask> will have a type like<br />
<br />
<haskell><br />
foo :: (Buffer b) => Worker b Int Int<br />
</haskell><br />
<br />
or something. (In particular, failing to write an explicit type signature will invoke the dreaded [[monomorphism restriction]].) Using existential types, we can avoid this:<br />
<br />
<haskell><br />
data Worker x y = forall b. Buffer b => Worker {buffer :: b, input :: x, output :: y}<br />
<br />
foo :: Worker Int Int<br />
</haskell><br />
<br />
The type of the buffer now does ''not'' appear in the <hask>Worker</hask> type at all.<br />
<br />
This has a number of consequences. First of all, it is now impossible for a function to demand a <hask>Worker</hask> having a specific type of buffer. Second, the type of <hask>foo</hask> can now be derived automatically without needing an explicit type signature. (No [[monomorphism restriction]].) Thirdly, since code now has ''no idea'' what type the <hask>buffer</hask> function returns, you are more limited in what you can do to it.<br />
<br />
In general, when you use a 'hidden' type in this way, you will usually want that type to belong to a specific class, or you will want to pass some functions along that can work on that type. Otherwise you'll have some value belonging to a random unknown type, and you won't be able to ''do'' anything to it!<br />
<br />
Note: You can use existential types to convert a more specific type into a less specific one. (See the examples below.) There is ''no way'' to perform the reverse conversion!<br />
<br />
== Examples ==<br />
<br />
===A short example===<br />
<br />
This illustrates creating a heterogeneous list, all of whose members implement "Show", and progressing through that list to show these items:<br />
<br />
<haskell><br />
data Obj = forall a. (Show a) => Obj a<br />
<br />
xs :: [Obj]<br />
xs = [Obj 1, Obj "foo", Obj 'c']<br />
<br />
doShow :: [Obj] -> String<br />
doShow [] = ""<br />
doShow ((Obj x):xs) = show x ++ doShow xs<br />
</haskell><br />
<br />
With output: <code>doShow xs ==> "1\"foo\"'c'"</code><br />
<br />
===Expanded example - rendering objects in a raytracer===<br />
<br />
====Problem statement====<br />
<br />
In a raytracer, a requirement is to be able to render several different objects (like a ball, mesh or whatever). The first step is a type class for Renderable like so:<br />
<br />
<haskell><br />
class Renderable a where<br />
boundingSphere :: a -> Sphere<br />
hit :: a -> [Fragment] -- returns the "fragments" of all hits with ray<br />
{- ... etc ... -}<br />
</haskell><br />
<br />
To solve the problem, the <hask>hit</hask> function must apply to several objects (like a sphere and a polygon for instance).<br />
<br />
<haskell><br />
hits :: Renderable a => [a] -> [Fragment]<br />
hits xs = sortByDistance $ concatMap hit xs<br />
</haskell><br />
<br />
However, this does not work as written since the elements of the list can be of '''SEVERAL''' different types (like a sphere and a polygon and a mesh etc. etc.) but<br />
lists need to have elements of the same type.<br />
<br />
====The solution====<br />
<br />
Use 'existential types' - an extension to Haskell that can be found in most compilers.<br />
<br />
The following example is based on GHC :<br />
<br />
<haskell><br />
{-# OPTIONS -fglasgow-exts #-}<br />
<br />
{- ...-}<br />
<br />
data AnyRenderable = forall a. Renderable a => AnyRenderable a<br />
<br />
instance Renderable AnyRenderable where<br />
boundingSphere (AnyRenderable a) = boundingSphere a<br />
hit (AnyRenderable a) = hit a<br />
{- ... -}<br />
</haskell><br />
<br />
Now, create lists with type <hask>[AnyRenderable]</hask>, for example,<br />
<haskell><br />
[ AnyRenderable x<br />
, AnyRenderable y<br />
, AnyRenderable z ]<br />
</haskell><br />
where x, y, z can be from different instances of <hask>Renderable</hask>.<br />
=== Dynamic dispatch mechanism of OOP ===<br />
<br />
'''Existential types''' in conjunction with type classes can be used to emulate the dynamic dispatch mechanism of object oriented programming languages. To illustrate this concept I show how a classic example from object oriented programming can be encoded in Haskell.<br />
<br />
<haskell><br />
class Shape_ a where<br />
perimeter :: a -> Double<br />
area :: a -> Double<br />
<br />
data Shape = forall a. Shape_ a => Shape a<br />
<br />
type Radius = Double<br />
type Side = Double<br />
<br />
data Circle = Circle Radius<br />
data Rectangle = Rectangle Side Side<br />
data Square = Square Side<br />
<br />
<br />
instance Shape_ Circle where<br />
perimeter (Circle r) = 2 * pi * r<br />
area (Circle r) = pi * r * r<br />
<br />
instance Shape_ Rectangle where<br />
perimeter (Rectangle x y) = 2*(x + y)<br />
area (Rectangle x y) = x * y<br />
<br />
instance Shape_ Square where<br />
perimeter (Square s) = 4*s<br />
area (Square s) = s*s<br />
<br />
instance Shape_ Shape where<br />
perimeter (Shape shape) = perimeter shape<br />
area (Shape shape) = area shape<br />
<br />
<br />
--<br />
-- Smart constructor<br />
--<br />
<br />
circle :: Radius -> Shape<br />
circle r = Shape (Circle r)<br />
<br />
rectangle :: Side -> Side -> Shape<br />
rectangle x y = Shape (Rectangle x y)<br />
<br />
square :: Side -> Shape<br />
square s = Shape (Square s)<br />
<br />
shapes :: [Shape]<br />
shapes = [circle 2.4, rectangle 3.1 4.4, square 2.1]<br />
</haskell><br />
<br />
(You may see other [[Smart constructors]] for other purposes).<br />
<br />
=== [[Generalised algebraic datatype]] ===<br />
<br />
The type of the <hask>parse</hask> function for [[Generalised algebraic datatype#Motivating example|this GADT]] is a good example to illustrate the concept of existential type.<br />
<br />
=== SomeException ===<br />
<hask>Control.Exception</hask> (see [http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Exception.html documentation]) provides extensible exceptions by making the core exception type, <hask>SomeException</hask>, an existential:<br />
<br />
<haskell><br />
class (Show e, Typeable e) => Exception e where<br />
toException :: e -> SomeException<br />
fromException :: SomeException -> Maybe e<br />
data SomeException = forall a. Exception a => SomeException a<br />
</haskell><br />
<br />
You can define your own exceptions by making them an instance of the <hask>Exception</hask> class. Then there are two basic ways of dealing with exceptions:<br />
#If you have a <hask>SomeException</hask> value, use <hask>fromException</hask>. This returns <hask>Just e</hask> if the exception is the type you want. If it's something else, you get <hask>Nothing</hask>. You could check multiple types using a guard. This is what you'll have to use if you're dealing with <hask>SomeException</hask>s in pure code.<br />
#If you're in IO and have an expression that might throw an exception, <hask>catch</hask> lets you catch it. (There's also a version generalised to other instances of <hask>MonadIO</hask> in the <hask>lifted-base</hask> package). Its second argument takes a handler, which is a function accepting an exception of the type you want. If the first argument throws an exception, <hask>catch</hask> uses the <hask>Typeable</hask> library's typesafe cast to try to convert it to the type you want, then (if it succeeded) passes it to the handler. You can apply <hask>catch</hask> many times to the same expression with handlers for different exception types.<br />
#Even if <hask>fromException</hask> doesn't turn up an exception type you know, and <hask>catch</hask> doesn't catch an exception type you know, you can still <hask>show</hask> the unknown exception, maybe after catching <hask>SomeException</hask>.<br />
<br />
==Alternate methods==<br />
===Concrete data types===<br />
====Universal instance of a Class====<br />
Here one way to simulate existentials (Hawiki note: (Borrowed from somewhere...))<br />
<br />
<br />
Suppose I have a type class Shape a<br />
<haskell><br />
type Point = (Float,Float)<br />
<br />
class Shape a where<br />
draw :: a -> IO ()<br />
translate :: a-> Point -> a<br />
<br />
</haskell><br />
<br />
Then we can pack shapes up into a [[concrete data type]] like this:<br />
<haskell><br />
data SHAPE = SHAPE (IO ()) (Point -> SHAPE)<br />
</haskell><br />
with a function like this<br />
<haskell><br />
packShape :: Shape a => a -> SHAPE<br />
packShape s = SHAPE (draw s) (\(x,y) -> packShape (translate s (x,y)))<br />
</haskell><br />
This would be useful if we needed a list of shapes that we would need to translate and draw.<br />
<br />
In fact we can make <hask>SHAPE</hask> an instance of <hask>Shape</hask>:<br />
<haskell><br />
instance Shape SHAPE where<br />
draw (SHAPE d t) = d<br />
translate (SHAPE d t) = t<br />
</haskell><br />
<br />
So SHAPE is a sort of universal instance.<br />
<br />
====Using constructors and combinators====<br />
Why bother with class <hask>Shape</hask>? Why not just go straight to<br />
<br />
<haskell><br />
data Shape = Shape {<br />
draw :: IO()<br />
translate :: (Int, Int) -> Shape<br />
}<br />
</haskell><br />
<br />
Then you can create a library of shape [[constructor]]s and [[combinator]]s<br />
that each have defined "draw" and "translate" in their "where" clauses.<br />
<br />
<haskell><br />
circle :: (Int, Int) -> Int -> Shape<br />
circle (x,y) r =<br />
Shape draw1 translate1<br />
where<br />
draw1 = ...<br />
translate1 (x1,y1) = circle (x+x1, y+y1) r<br />
<br />
shapeGroup :: [Shape] -> Shape<br />
shapeGroup shapes = Shape draw1 translate1<br />
where<br />
draw1 = mapM_ draw shapes<br />
translate1 v = shapeGroup $ map (translate v) shapes<br />
</haskell><br />
<br />
===Cases that really require existentials===<br />
<br />
There are cases where this sort of trick doesn't work. Here are two examples from a haskell mailing list discussion (from K. Claussen) that don't seem expressible without<br />
existentials. (But maybe one can rethink the whole thing :)<br />
<haskell><br />
data Expr a = Val a | forall b . Apply (Expr (b -> a)) (Expr b)<br />
</haskell><br />
and<br />
<haskell><br />
data Action = forall b . Act (IORef b) (b -> IO ())<br />
</haskell><br />
(Maybe this last one could be done as a <hask>type Act (IORef b) (IORef b -> IO ())</hask> then we could hide the <hask>IORef</hask> as above, that is go ahead and apply the second argument to the first)<br />
<br />
=== Existentials in terms of "forall" ===<br />
It is also possible to express existentials as type expressions directly (without a <hask>data</hask> declaration) with RankNTypes. Taking the above example:<br />
<br />
<haskell>data Obj = forall a. (Show a) => Obj a</haskell><br />
<br />
the type <hask>Obj</hask> is equivalent to:<br />
<br />
<haskell>forall r. (forall a. Show a => a -> r) -> r</haskell><br />
<br />
(the leading <hask>forall r.</hask> is optional unless the expression is part of another expression). The conversions are:<br />
<br />
<haskell><br />
fromObj :: Obj <br />
-> forall r. (forall a. Show a => a -> r) -> r<br />
fromObj (Obj x) k = k x<br />
<br />
toObj :: (forall r. (forall a. Show a => a -> r) -> r) <br />
-> Obj<br />
toObj f = f Obj<br />
</haskell><br />
<br />
== Examples from the [http://www.cs.uu.nl/wiki/Ehc/ Essential Haskell Compiler] project ==<br />
<br />
See the [http://www.cs.uu.nl/wiki/Ehc/#On_EHC documentation on EHC], each paper at the ''Version 4'' part:<br />
* Chapter 8 (EH4) of Atze Dijkstra's [http://www.cs.uu.nl/groups/ST/Projects/ehc/ehc-book.pdf Essential Haskell PhD thesis] (most recent version). A detailed explanation. It explains also that existential types can be expressed in Haskell, but their use is restricted to data declarations, and the notation (using keyword <hask>forall</hask>) may be confusing. In Essential Haskell, existential types can occur not only in data declarations, and a separate keyword <hask>exists</hask> is used for their notation.<br />
* [http://www.cs.uu.nl/wiki/pub/Ehc/WebHome/20050107-eh-intro.pdf Essential Haskell Compiler overview]<br />
* [http://www.cs.uu.nl/wiki/Ehc/Examples#EH_4_forall_and_exists_everywher Examples]<br />
<br />
==See also==<br />
* A mailinglist discussion: http://haskell.org/pipermail/haskell-cafe/2003-October/005231.html<br />
* An example of encoding existentials using RankTwoPolymorphism: http://haskell.org/pipermail/haskell-cafe/2003-October/005304.html<br />
* Another mailing list discussion (functional vs OO approaches): http://www.haskell.org/pipermail/haskell/2005-June/016058.html<br />
* Just another one: http://www.haskell.org/pipermail/haskell-cafe/2008-January/037950.html "type question again"<br />
* Haskell antipattern: Existential typeclass http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/<br />
<br />
=== Trac ===<br />
<br />
[http://hackage.haskell.org/trac/haskell-prime/wiki/ExistentialQuantification Existential Quantification] is a detailed material on the topic. It has link also to the smaller [http://hackage.haskell.org/trac/haskell-prime/wiki/ExistentialQuantifier Existential Quantifier] page.<br />
<br />
[[Category:Idioms]]<br />
[[Category:Glossary]]<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Context_alias&diff=61242Context alias2016-10-27T03:07:24Z<p>Ryantm: </p>
<hr />
<div>Context aliases, also known as class aliases, are a long-requested feature of Haskell. This feature would allow class hierarchies to be restructured without breaking compatibility to a certain degree. Also, it would make fine-grained class hierarchies usable.<br />
<br />
This page is somewhat historical. Currently, with the [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#the-constraint-kind ConstraintKinds] extension, you can write:<br />
<br />
type Foo a = (Bar a, Baz a, Quux a, Fleeble a)<br />
<br />
and use ''Foo a'' as a constraint. You cannot, however, use it in a ''deriving'' clause; you must derive the individual constraints instead.<br />
<br />
== The proposal ==<br />
<br />
=== The original class alias proposal ===<br />
<br />
The original proposal can be found on [http://repetae.net/recent/out/classalias.html a page on John Meacham’s website].<br />
<br />
==== Class aliases with new methods ====<br />
I would like to emphasize an important point from the original proposal that was not emphasized enough:<br />
<br />
Lets look at one of the examples from the original proposal:<br />
<br />
class SemiLatticeJoin a where<br />
join :: a -> a -> a<br />
<br />
class BoundedBelow a where<br />
bottom :: a<br />
<br />
class BoundedBelowJoinable a = (BoundedBelow a, SemiLatticeJoin a) where<br />
joins :: [a] -> a<br />
joins xs = foldl join bottom xs<br />
<br />
Notice that ''BoundedBelowJoinable'' doesn't have the ''alias'' keyword. Is this a syntax error or is it allowed? It is allowed because ''BoundedBelowJoinable'' is not just an alias for ''(BoundedBelow a, SemiLatticeJoin a)''. It also declares a new method called ''joins''.<br />
<br />
So why is this usefull?<br />
<br />
Users can declare instances for ''BoundedBelow'' and ''SemiLatticeJoin'' and get ''joins'' for free or they can declare an instance for ''BoundedBelowJoinable'' and define an optimized ''joins'' for their type.<br />
<br />
Lets look at another example why this ability, to give a class alias new methods, is useful. Again I take an example from the original proposal but I slightly change it:<br />
<br />
The current ''Num'' class in the Prelude is (more or less) this<br />
<br />
class Num a where<br />
(+) :: a -> a -> a<br />
(*) :: a -> a -> a<br />
(-) :: a -> a -> a<br />
negate :: a -> a<br />
fromInteger :: Integer -> a<br />
<br />
Ideally we would want to split it up using classes from the [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/monoids monoids package]:<br />
<br />
class Monoid a where<br />
mempty :: a<br />
mappend :: a -> a -> a<br />
<br />
class Monoid a => Group a where<br />
gnegate :: a -> a<br />
minus :: a -> a -> a<br />
gsubtract :: a -> a -> a<br />
<br />
gnegate = minus mempty<br />
a `minus` b = a `mappend` gnegate b <br />
a `gsubtract` b = gnegate a `mappend` b<br />
<br />
class Multiplicative a where<br />
one :: a<br />
times :: a -> a -> a<br />
<br />
class FromInteger a where<br />
fromInteger :: Integer -> a<br />
<br />
But this creates some problems as mentioned in the proposal:<br />
<br />
* People using the new prelude have to write the ungainly (Monoid a, Group a, Multiplicative a, FromInteger a) and declare separate instances for all of them.<br />
* If at some point a HasZero class is separated out then everyone needs to modify their instance declarations.<br />
* Num still must be declared if you want it to work with old prelude functions, containing completely redundant information.<br />
* All the problems mentioned in the second section of the proposal about alternate preludes in general.<br />
<br />
We can solve all of them by creating a class alias:<br />
<br />
class alias Num a = (Monoid a, Group a, Multiplicative a, FromInteger a)<br />
<br />
Or can we? Unfortunately this ''Num'' is different than the original ''Num''. Because instead of the methods ''(+)'', ''(-)'', ''(*)'' and ''negate'' we have ''mappend'', ''minus'', ''times'' and ''gnegate''.<br />
<br />
Fortunately we can add the original names as new methods to the class alias and give them default definitions in terms of the new names: <br />
<br />
class Num a = (Monoid a, Group a, Multiplicative a, FromInteger a) where<br />
<br />
-- Default implementations of existing methods:<br />
mempty = 0<br />
mappend = (+)<br />
<br />
one = 1<br />
times = (*)<br />
<br />
minus = (-)<br />
gnegate = negate<br />
<br />
-- New methods with default implementations:<br />
(+) :: a -> a -> a<br />
(+) = mappend<br />
<br />
(*) :: a -> a -> a<br />
(*) = times<br />
<br />
(-) :: a -> a -> a<br />
(-) = minus<br />
<br />
negate :: a -> a<br />
negate = gnegate<br />
<br />
The question is: how is the above translated? <br />
<br />
The new methods from ''Num'' should be placed in a new "internal" class: ''Num_NEW_METHODS'':<br />
<br />
class Num_NEW_METHODS a where<br />
(+) :: a -> a -> a<br />
(*) :: a -> a -> a<br />
(-) :: a -> a -> a<br />
negate :: a -> a<br />
<br />
What happens when a user defines an instance for ''Num''? Lets look at an example:<br />
<br />
Say a user defines the natural numbers and makes them an instance of the ''Num'' class alias:<br />
<br />
data N = Z | S N<br />
<br />
instance Num N where<br />
Z + y = y<br />
S x + y = S (x + y)<br />
<br />
Z * _ = Z<br />
S Z * y = y<br />
S x * y = y + x * y<br />
<br />
x - Z = x<br />
S x - S y = x - y<br />
<br />
fromInteger 0 = Z<br />
fromInteger (n+1) = S n -- You gotta love n+k patterns!<br />
<br />
Note that the other methods of ''Num'' like ''mempty'', ''mappend'', ''one'' and ''times'' have default implementations in terms of the above. <br />
<br />
First of all an instance for ''Num_NEW_METHODS'' will be defined:<br />
<br />
instance Num_NEW_METHODS N where<br />
Z + y = y<br />
S x + y = S (x + y)<br />
<br />
Z * _ = Z<br />
S Z * y = y<br />
S x * y = y + x * y<br />
<br />
x - Z = x<br />
S x - S y = x - y<br />
<br />
negate = gnegate<br />
<br />
Then the other instances are defined using methods from ''Num_NEW_METHODS'':<br />
<br />
instance Monoid N where<br />
mempty = 0<br />
mappend = (+)<br />
<br />
instance Group N where<br />
minus = (-)<br />
<br />
instance Multiplicative N where<br />
one = 1<br />
times = (*)<br />
<br />
instance FromInteger N where<br />
fromInteger 0 = Z<br />
fromInteger (n+1) = S n -- You gotta love n+k patterns!<br />
<br />
In conclusion, a class alias is a name for a context plus optionally a new class. The question is how useful this ability is.<br />
<br />
The ''BoundedBelowJoinable'' could also be defined as a normal class with the necessary superclasses: <br />
<br />
class (BoundedBelow a, SemiLatticeJoin a) => BoundedBelowJoinable a where<br />
joins :: [a] -> a<br />
joins xs = foldl join bottom xs<br />
<br />
However, user now don't get a ''BoundedBelowJoinable'' for free when they have defined instances for ''BoundedBelow'' and ''SemiLatticeJoin''.<br />
<br />
=== Improvements ===<br />
<br />
==== “Context alias” instead of “class alias” ====<br />
<br />
A “class alias” actually doesn’t stand for a class but for a context (or a part of a context). So it might be better to choose a slightly different syntax:<br />
<br />
context Foobar a = (Foo a, Bar a)<br />
<br />
However if we allow class "aliases" to be extended with new methods then a class "alias" is not just a name for a context. (It is actually a context with a new class)<br />
<br />
Maybe we should keep the syntax really light like:<br />
<br />
class Foobar a = (Foo a, Bar a)<br />
<br />
==== Superclass constraints ====<br />
<br />
John Meacham proposes the following syntax for class aliases (context aliases) with superclass constraints:<br />
<br />
class alias Num a = Eq a => (Additive a, Multiplicative a)<br />
<br />
This is not consistent with the superclass syntax of class declarations. I think, we should use this syntax:<br />
<br />
class alias Eq a => Num a = (Additive a, Multiplicative a)<br />
<br />
Or better:<br />
<br />
context Eq a => Num a = (Additive a, Multiplicative a)<br />
<br />
==== Functional dependencies ====<br />
<br />
Does the following make sense?<br />
<br />
class alias A a b = (B a b, C a b) | a -> b where ...<br />
<br />
==== Associated data types and type synonyms ====<br />
<br />
When <tt>{-# LANGUAGE TypeFamilies #-}</tt> is enabled, classes may declare [[GHC/Type_families|associated data types or associated type synonyms]].<br />
<br />
If we allow class aliases to be extended with new methods, I think it make sense to also allow them to be extended with associated data types and type synonyms:<br />
<br />
class A a = (B a, C a) where<br />
type T a<br />
data D a<br />
<br />
==== Equality constraints ====<br />
<br />
When <tt>{-# LANGUAGE TypeFamilies #-}</tt> is enabled, type contexts can include [[GHC/Type_families#Equality_constraints|equality constraints]] (<tt>t1 ~ t2</tt>).<br />
<br />
It makes sense to also allow them in class aliases (context aliases)<br />
<br />
==== Things to have in mind ====<br />
<br />
In order to get the context alias extension well, we should have an eye on problems we might want to solve with the help of context aliases. Here are some:<br />
<br />
* <hask>MonadPlus</hask> should just be a combination of <hask>Alternative</hask> and <hask>Monad</hask> (actually, <hask>Alternative f</hask> should just be a combination of <hask>Applicative f</hask> and <hask>forall a. Monoid (f a)</hask>)<br />
<br />
* <hask>Applicative</hask> should be a superclass of <hask>Monad</hask><br />
<br />
<br />
== Implementation ==<br />
<br />
Starting an implementation of context aliases is planned for the [[Hac5|5th Haskell Hackathon]].<br />
<br />
Roadmap:<br />
# Context synonym declarations<br />
# Context synonym instances<br />
# New methods in 'context synonym'<br />
# Context synonym super classes/contexts</div>Ryantmhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=61230Template Haskell2016-10-25T17:36:44Z<p>Ryantm: </p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell Template Haskell section}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [http://research.microsoft.com/en-us/um/people/simonpj/tmp/notes2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [String]<br />
as = ["a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses syb to address some of the pain of dealing with the rather large data types. <br />
<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybes modName input = let<br />
<br />
rename :: GenericT<br />
rename = mkT $ \n -> if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
addMaybe :: GenericM Q<br />
addMaybe = mkM $ \(n :: Name, s :: Strict, ty :: Type) -> do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
in everywhere rename `fmap` everywhereM addMaybe input<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI d <- reify n<br />
addMaybes (nameModule n) d<br />
</haskell><br />
<br />
mkOptional then generates a new data type with all Names in that module with an added suffix _opt. Here is an example of its use:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
data Foo = Foo { a,b,c,d,e :: Double, f :: Int }<br />
<br />
mapM mkOptional [''Foo]<br />
</haskell><br />
<br />
Generates something like<br />
<haskell><br />
data Foo_opt = Foo_opt {a_opt :: Maybe Double, ..... f_opt :: Maybe Int}<br />
</haskell><br />
<br />
<br />
<br />
[[Category:Language extensions]]</div>Ryantmhttps://wiki.haskell.org/index.php?title=Template:GHCUsersGuide&diff=61229Template:GHCUsersGuide2016-10-25T17:35:15Z<p>Ryantm: Created page with "'''The [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ GHC Users Guide] has a [{{{1}}}].'''"</p>
<hr />
<div>'''The [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ GHC Users Guide] has a [{{{1}}}].'''</div>Ryantmhttps://wiki.haskell.org/index.php?title=Haskell_program_coverage&diff=60068Haskell program coverage2015-09-04T13:44:20Z<p>Ryantm: /* Hpc with Cabal */</p>
<hr />
<div>[[Category:Development tools]] [[Category:Applications]]<br />
== What is hpc? ==<br />
<br />
Hpc is a tool-kit to record and display Haskell program coverage. Hpc<br />
includes tools that instrument Haskell programs to record program<br />
coverage, run instrumented programs, and display the coverage<br />
information obtained.<br />
<br />
Hpc works by applying a source-to-source transformation; this<br />
transformation also generates as a by-product a program-index file<br />
(.pix) and module-index files (.mix). The transformed program is<br />
compiled with a library; in addition to its usual run-time behaviour<br />
the program generates a coverage record in a program-ticks file<br />
(.tix). If the program is run more than once, coverage data is<br />
accumulated to reflect all runs.<br />
<br />
Hpc provides coverage information of two kinds: source coverage and<br />
boolean-control coverage. Source coverage is the extent to which every<br />
part of the program was used, measured at three different levels:<br />
declarations (both top-level and local), alternatives (among several<br />
equations or case branches) and expressions (at every level). Boolean<br />
coverage is the extent to which each of the values True and False is<br />
obtained in every syntactic boolean context (ie. guard, condition,<br />
qualifier).<br />
<br />
Hpc displays both kinds of information in two different ways: textual<br />
reports with summary statistics (hpc-report) and sources with colour<br />
mark-up (hpc-source).<br />
<br />
== Downloading ==<br />
<br />
This version of hpc is available under a BSD-style license for free<br />
use by all sectors of the Haskell community. The hpc-trans tool was based<br />
on components from the nhc98 compiler or from the hat tracing system,<br />
and we gladly acknowledge the contribution of the original authors.<br />
<br />
The latest version is version 0.4 and can be found at: <br />
http://projects.unsafePerformIO.com/hpc<br />
<br />
== Examples ==<br />
<br />
=== Example textual output from hpc-report ===<br />
<br />
<nowiki>-----<module Main>-----</nowiki><br />
67% expressions used (72/106)<br />
14% boolean coverage (1/7)<br />
16% guards (1/6), 2 always True, 2 always False, 1 unevaluated<br />
0% 'if' conditions (0/1), 1 always True<br />
100% qualifiers (0/0)<br />
42% alternatives used (3/7)<br />
88% local declarations used (8/9)<br />
80% top-level declarations used (4/5)<br />
unused declarations:<br />
position<br />
showRecip.p<br />
<br />
=== Example of HTML output from hpc-markup ===<br />
<br />
[[Image:hpcexample.gif]]<br />
<br />
The HTML output highlights parts of the program <font style="background: yellow">never evaluated</font>; it also highlights boolean conditions for which recorded evaluations are <font style="background: green">always True</font><br />
or <font style="background: red">always False</font>.<br />
<br />
=== Example of HTML Summary from hpc-markup ===<br />
<br />
This is an example of the table that provides the summary of coverage,<br />
with links the the individually marked-up files.<br />
<br />
<table width="100%" border=1><br />
<tr><th rowspan=2>module</th><th colspan=3>Top Level Definitions</th><th colspan=3>Alternatives</th><th colspan=3>Expressions</th></tr><tr><th>%</th><th colspan=2>covered / total</th><th>%</th><th colspan=2>covered / total</th><th>%</th><th colspan=2>covered / total</th></tr><tr><br />
<td>&nbsp;&nbsp;<tt>module CSG</tt></td><br />
<td align="right">100 %</td><td>0/0</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">100 %</td><td>0/0</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">100 %</td><td>0/0</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Construct</tt></td><br />
<td align="right">48 %</td><td>17/35</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="48%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">52 %</td><td>25/48</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="52%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">60 %</td><td>381/635</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="60%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Data</tt></td><br />
<td align="right">24 %</td><td>6/25</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="24%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">13 %</td><td>11/81</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="13%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">39 %</td><td>254/646</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="39%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Eval</tt></td><br />
<td align="right">70 %</td><td>22/31</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="70%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">60 %</td><td>65/108</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="60%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">57 %</td><td>361/628</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="57%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Geometry</tt></td><br />
<td align="right">75 %</td><td>42/56</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="75%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">69 %</td><td>45/65</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="69%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">70 %</td><td>300/427</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="70%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Illumination</tt></td><br />
<td align="right">61 %</td><td>11/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="61%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">49 %</td><td>46/93</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="49%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">46 %</td><td>279/600</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="46%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Intersections</tt></td><br />
<td align="right">63 %</td><td>14/22</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="63%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">38 %</td><td>83/213</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="38%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">38 %</td><td>382/1001</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="38%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Interval</tt></td><br />
<td align="right">47 %</td><td>8/17</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="47%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">41 %</td><td>16/39</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="41%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">41 %</td><td>69/165</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="41%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Main</tt></td><br />
<td align="right">100 %</td><td>1/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">100 %</td><td>1/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">100 %</td><td>6/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Misc</tt></td><br />
<td align="right">0 %</td><td>0/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="0%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">0 %</td><td>0/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="0%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">0 %</td><td>0/10</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="0%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Parse</tt></td><br />
<td align="right">80 %</td><td>16/20</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="80%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">68 %</td><td>26/38</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="68%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">72 %</td><td>192/264</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="72%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Primitives</tt></td><br />
<td align="right">16 %</td><td>1/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">16 %</td><td>1/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">20 %</td><td>5/24</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="20%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Surface</tt></td><br />
<td align="right">36 %</td><td>4/11</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="36%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">24 %</td><td>13/53</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="24%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">18 %</td><td>43/231</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="18%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
</table><br />
<br />
== Hpc toolkit ==<br />
<br />
The Hpc Toolkit has three parts<br />
* A set of tools for instrumenting Haskell, and interpreting the results on a coverage run.<br />
* A set of scripts to make using these tools easier.<br />
* An open common file format, uses by all the tools.<br />
<br />
=== Hpc tools ===<br />
<br />
There are currently three tools provided by hpc, as well as a new option for GHC 6.7.<br />
<br />
Tools<br />
<br />
* hpc-trans - translates Haskell into instrumented Haskell<br />
* hpc-report - Read the output of a coverage run, report a summary<br />
* hpc-markup - Read the output of a coverage run, markup the source<br />
<br />
Compiler Options<br />
<br />
* -fhpc - a new GHC option, that automatically instruments Haskell programs on the fly, using a similar algorithm to hpc-trans.<br />
<br />
=== Hpc scripts ===<br />
<br />
* hpc-build<br />
* hpc-run<br />
<br />
<br />
=== Hpc file formats ===<br />
<br />
There are two file formats used by Hpc externally, and one internally<br />
by hpc-trans.<br />
<br />
* tix - Coverage information generated by the execution of an instrumented program.<br />
* mix - Information about each tick-box inside a module, including style of tick box, and location in the source.<br />
* pix - used only by hpc-trans, stores a list<br />
<br />
=== Example ===<br />
<br />
Suppose you have run your tests and collected the coverage results in a .tix file (you don't have to do anything to collect the results - hpc will keep adding coverage information to the .tix file).<br />
<br />
Now you want to see how good your testing was:<br />
<br />
hpc report GenDesc.exe --hpcdir=..\src\.hpc --srcdir=..\src --per-module --include=Utils.Substitution<br />
<br />
<nowiki>-----<module Utils.Substitution>-----</nowiki><br />
65% expressions used (59/90)<br />
33% boolean coverage (1/3)<br />
0% guards (0/1), 1 always True<br />
50% 'if' conditions (1/2), 1 always True<br />
100% qualifiers (0/0)<br />
62% alternatives used (5/8)<br />
66% local declarations used (2/3)<br />
71% top-level declarations used (5/7)<br />
<br />
But you know that some of the source statements are assertions and should never be executed. First create a draft overlay that provides 100% coverage.<br />
<br />
hpc draft --hpcdir=..\src\.hpc --srcdir=..\src GenDesc.exe.tix > myDraft.txt<br />
<br />
You can then create a .tix file from the overlay.<br />
<br />
hpc overlay --hpcdir=..\src\.hpc --srcdir=..\src myDraft.txt > myDraft.tix<br />
<br />
And combine these two .tix files.<br />
<br />
hpc combine GenDesc.exe.tix myDraft2.tix --union > idem.tix<br />
<br />
Now you get a report that doesn't include assertions e.g. calls to assertM and error (although I'm basing this on observation - I couldn't find any documentation on this).<br />
<br />
hpc report idem --hpcdir=..\src\.hpc --srcdir=..\src --per-module<br />
--include=Utils.Substitution<br />
<br />
<nowiki>-----<module Utils.Substitution>-----</nowiki><br />
91% expressions used (82/90)<br />
33% boolean coverage (1/3)<br />
0% guards (0/1), 1 always True<br />
50% 'if' conditions (1/2), 1 always True<br />
100% qualifiers (0/0)<br />
87% alternatives used (7/8)<br />
66% local declarations used (2/3)<br />
71% top-level declarations used (5/7)<br />
<br />
But you still know that some of the functions should not be tested; they are there just in case you need to make some performance improvements in the future.<br />
<br />
Create an overlay file using the draft overlay as a template.<br />
<br />
module "Utils.Substitution" {<br />
tick function "getFreesShallow" [future];<br />
tick function "getFreesUsingPadrec" [future];<br />
}<br />
<br />
Create a .tix file from it.<br />
<br />
hpc overlay --hpcdir=..\src\.hpc --srcdir=..\src myAnnot.txt > myAnnot.tix<br />
<br />
And then combine it with the automatically generated exclusions .tix file.<br />
<br />
hpc combine idem.tix myAnnot.tix --union > excludeFuture.tix<br />
<br />
Now our report gives us (almost) what we want: 100% coverage.<br />
<br />
hpc report excludeFuture --hpcdir=..\src\.hpc --srcdir=..\src --per-module<br />
--include=Utils.Substitution<br />
<br />
<nowiki>-----<module Utils.Substitution>-----</nowiki><br />
100% expressions used (90/90)<br />
33% boolean coverage (1/3)<br />
0% guards (0/1), 1 always True<br />
50% 'if' conditions (1/2), 1 always True<br />
100% qualifiers (0/0)<br />
100% alternatives used (8/8)<br />
100% local declarations used (3/3)<br />
100% top-level declarations used (7/7)<br />
<br />
Sadly there is no documentation on how to exclude boolean coverage.<br />
<br />
== Hpc quirks ==<br />
<br />
Hpc (at least with 6.10.1) is not happy with literate haskell or with cpp. Even if your file contains no cpp, hpc will give spurious results if you use the cpp option on the command line. One way round both of these problems is to pre-process the source by hand with something like<br />
<br />
<nowiki>ghc -E -optP-P -cpp Foo.hs</nowiki><br />
<br />
and then remove the line<br />
<br />
<nowiki>{-# LINE 1 "Foo.hs" #-}</nowiki><br />
<br />
Don't use strip on your executables. I'm guessing hpc stashes information in the executable which strip removes.<br />
<br />
== Hpc with a Cabal project ==<br />
<br />
After installing HPC, you need to clear out your build with clean so every file can be built and enable coverage with configure:<br />
<br />
cabal clean<br />
cabal configure --enable-tests --enable-coverage<br />
cabal test<br />
<br />
----<br />
<br />
We hope you find this tool-kit useful. If you have any comments or<br />
feedback, please feel free to email us.<br />
<br />
Andy Gill (andy@galois.com)<br />
Colin Runciman (colin@cs.york.ac.uk)</div>Ryantmhttps://wiki.haskell.org/index.php?title=Haskell_program_coverage&diff=60067Haskell program coverage2015-09-04T13:41:33Z<p>Ryantm: add new section</p>
<hr />
<div>[[Category:Development tools]] [[Category:Applications]]<br />
== What is hpc? ==<br />
<br />
Hpc is a tool-kit to record and display Haskell program coverage. Hpc<br />
includes tools that instrument Haskell programs to record program<br />
coverage, run instrumented programs, and display the coverage<br />
information obtained.<br />
<br />
Hpc works by applying a source-to-source transformation; this<br />
transformation also generates as a by-product a program-index file<br />
(.pix) and module-index files (.mix). The transformed program is<br />
compiled with a library; in addition to its usual run-time behaviour<br />
the program generates a coverage record in a program-ticks file<br />
(.tix). If the program is run more than once, coverage data is<br />
accumulated to reflect all runs.<br />
<br />
Hpc provides coverage information of two kinds: source coverage and<br />
boolean-control coverage. Source coverage is the extent to which every<br />
part of the program was used, measured at three different levels:<br />
declarations (both top-level and local), alternatives (among several<br />
equations or case branches) and expressions (at every level). Boolean<br />
coverage is the extent to which each of the values True and False is<br />
obtained in every syntactic boolean context (ie. guard, condition,<br />
qualifier).<br />
<br />
Hpc displays both kinds of information in two different ways: textual<br />
reports with summary statistics (hpc-report) and sources with colour<br />
mark-up (hpc-source).<br />
<br />
== Downloading ==<br />
<br />
This version of hpc is available under a BSD-style license for free<br />
use by all sectors of the Haskell community. The hpc-trans tool was based<br />
on components from the nhc98 compiler or from the hat tracing system,<br />
and we gladly acknowledge the contribution of the original authors.<br />
<br />
The latest version is version 0.4 and can be found at: <br />
http://projects.unsafePerformIO.com/hpc<br />
<br />
== Examples ==<br />
<br />
=== Example textual output from hpc-report ===<br />
<br />
<nowiki>-----<module Main>-----</nowiki><br />
67% expressions used (72/106)<br />
14% boolean coverage (1/7)<br />
16% guards (1/6), 2 always True, 2 always False, 1 unevaluated<br />
0% 'if' conditions (0/1), 1 always True<br />
100% qualifiers (0/0)<br />
42% alternatives used (3/7)<br />
88% local declarations used (8/9)<br />
80% top-level declarations used (4/5)<br />
unused declarations:<br />
position<br />
showRecip.p<br />
<br />
=== Example of HTML output from hpc-markup ===<br />
<br />
[[Image:hpcexample.gif]]<br />
<br />
The HTML output highlights parts of the program <font style="background: yellow">never evaluated</font>; it also highlights boolean conditions for which recorded evaluations are <font style="background: green">always True</font><br />
or <font style="background: red">always False</font>.<br />
<br />
=== Example of HTML Summary from hpc-markup ===<br />
<br />
This is an example of the table that provides the summary of coverage,<br />
with links the the individually marked-up files.<br />
<br />
<table width="100%" border=1><br />
<tr><th rowspan=2>module</th><th colspan=3>Top Level Definitions</th><th colspan=3>Alternatives</th><th colspan=3>Expressions</th></tr><tr><th>%</th><th colspan=2>covered / total</th><th>%</th><th colspan=2>covered / total</th><th>%</th><th colspan=2>covered / total</th></tr><tr><br />
<td>&nbsp;&nbsp;<tt>module CSG</tt></td><br />
<td align="right">100 %</td><td>0/0</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">100 %</td><td>0/0</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">100 %</td><td>0/0</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Construct</tt></td><br />
<td align="right">48 %</td><td>17/35</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="48%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">52 %</td><td>25/48</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="52%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">60 %</td><td>381/635</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="60%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Data</tt></td><br />
<td align="right">24 %</td><td>6/25</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="24%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">13 %</td><td>11/81</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="13%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">39 %</td><td>254/646</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="39%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Eval</tt></td><br />
<td align="right">70 %</td><td>22/31</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="70%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">60 %</td><td>65/108</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="60%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">57 %</td><td>361/628</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="57%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Geometry</tt></td><br />
<td align="right">75 %</td><td>42/56</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="75%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">69 %</td><td>45/65</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="69%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">70 %</td><td>300/427</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="70%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Illumination</tt></td><br />
<td align="right">61 %</td><td>11/18</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="61%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">49 %</td><td>46/93</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="49%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">46 %</td><td>279/600</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="46%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Intersections</tt></td><br />
<td align="right">63 %</td><td>14/22</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="63%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">38 %</td><td>83/213</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="38%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">38 %</td><td>382/1001</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="38%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Interval</tt></td><br />
<td align="right">47 %</td><td>8/17</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="47%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">41 %</td><td>16/39</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="41%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">41 %</td><td>69/165</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="41%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Main</tt></td><br />
<td align="right">100 %</td><td>1/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">100 %</td><td>1/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">100 %</td><td>6/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="100%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Misc</tt></td><br />
<td align="right">0 %</td><td>0/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="0%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">0 %</td><td>0/1</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="0%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">0 %</td><td>0/10</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="0%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Parse</tt></td><br />
<td align="right">80 %</td><td>16/20</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="80%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">68 %</td><td>26/38</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="68%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">72 %</td><td>192/264</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="72%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Primitives</tt></td><br />
<td align="right">16 %</td><td>1/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">16 %</td><td>1/6</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="16%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">20 %</td><td>5/24</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="20%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<tr><br />
<td>&nbsp;&nbsp;<tt>module Surface</tt></td><br />
<td align="right">36 %</td><td>4/11</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="36%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">24 %</td><td>13/53</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="24%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table><td align="right">18 %</td><td>43/231</td><td width=100><table cellpadding=0 cellspacing=0 width="100" style="background-color: #f25913"><tr><td><table cellpadding=0 cellspacing=0 width="18%"><tr><td height=12 style="background-color: #60de51"></td></tr></table></td></tr></table></tr><br />
<br />
</table><br />
<br />
== Hpc toolkit ==<br />
<br />
The Hpc Toolkit has three parts<br />
* A set of tools for instrumenting Haskell, and interpreting the results on a coverage run.<br />
* A set of scripts to make using these tools easier.<br />
* An open common file format, uses by all the tools.<br />
<br />
=== Hpc tools ===<br />
<br />
There are currently three tools provided by hpc, as well as a new option for GHC 6.7.<br />
<br />
Tools<br />
<br />
* hpc-trans - translates Haskell into instrumented Haskell<br />
* hpc-report - Read the output of a coverage run, report a summary<br />
* hpc-markup - Read the output of a coverage run, markup the source<br />
<br />
Compiler Options<br />
<br />
* -fhpc - a new GHC option, that automatically instruments Haskell programs on the fly, using a similar algorithm to hpc-trans.<br />
<br />
=== Hpc scripts ===<br />
<br />
* hpc-build<br />
* hpc-run<br />
<br />
<br />
=== Hpc file formats ===<br />
<br />
There are two file formats used by Hpc externally, and one internally<br />
by hpc-trans.<br />
<br />
* tix - Coverage information generated by the execution of an instrumented program.<br />
* mix - Information about each tick-box inside a module, including style of tick box, and location in the source.<br />
* pix - used only by hpc-trans, stores a list<br />
<br />
=== Example ===<br />
<br />
Suppose you have run your tests and collected the coverage results in a .tix file (you don't have to do anything to collect the results - hpc will keep adding coverage information to the .tix file).<br />
<br />
Now you want to see how good your testing was:<br />
<br />
hpc report GenDesc.exe --hpcdir=..\src\.hpc --srcdir=..\src --per-module --include=Utils.Substitution<br />
<br />
<nowiki>-----<module Utils.Substitution>-----</nowiki><br />
65% expressions used (59/90)<br />
33% boolean coverage (1/3)<br />
0% guards (0/1), 1 always True<br />
50% 'if' conditions (1/2), 1 always True<br />
100% qualifiers (0/0)<br />
62% alternatives used (5/8)<br />
66% local declarations used (2/3)<br />
71% top-level declarations used (5/7)<br />
<br />
But you know that some of the source statements are assertions and should never be executed. First create a draft overlay that provides 100% coverage.<br />
<br />
hpc draft --hpcdir=..\src\.hpc --srcdir=..\src GenDesc.exe.tix > myDraft.txt<br />
<br />
You can then create a .tix file from the overlay.<br />
<br />
hpc overlay --hpcdir=..\src\.hpc --srcdir=..\src myDraft.txt > myDraft.tix<br />
<br />
And combine these two .tix files.<br />
<br />
hpc combine GenDesc.exe.tix myDraft2.tix --union > idem.tix<br />
<br />
Now you get a report that doesn't include assertions e.g. calls to assertM and error (although I'm basing this on observation - I couldn't find any documentation on this).<br />
<br />
hpc report idem --hpcdir=..\src\.hpc --srcdir=..\src --per-module<br />
--include=Utils.Substitution<br />
<br />
<nowiki>-----<module Utils.Substitution>-----</nowiki><br />
91% expressions used (82/90)<br />
33% boolean coverage (1/3)<br />
0% guards (0/1), 1 always True<br />
50% 'if' conditions (1/2), 1 always True<br />
100% qualifiers (0/0)<br />
87% alternatives used (7/8)<br />
66% local declarations used (2/3)<br />
71% top-level declarations used (5/7)<br />
<br />
But you still know that some of the functions should not be tested; they are there just in case you need to make some performance improvements in the future.<br />
<br />
Create an overlay file using the draft overlay as a template.<br />
<br />
module "Utils.Substitution" {<br />
tick function "getFreesShallow" [future];<br />
tick function "getFreesUsingPadrec" [future];<br />
}<br />
<br />
Create a .tix file from it.<br />
<br />
hpc overlay --hpcdir=..\src\.hpc --srcdir=..\src myAnnot.txt > myAnnot.tix<br />
<br />
And then combine it with the automatically generated exclusions .tix file.<br />
<br />
hpc combine idem.tix myAnnot.tix --union > excludeFuture.tix<br />
<br />
Now our report gives us (almost) what we want: 100% coverage.<br />
<br />
hpc report excludeFuture --hpcdir=..\src\.hpc --srcdir=..\src --per-module<br />
--include=Utils.Substitution<br />
<br />
<nowiki>-----<module Utils.Substitution>-----</nowiki><br />
100% expressions used (90/90)<br />
33% boolean coverage (1/3)<br />
0% guards (0/1), 1 always True<br />
50% 'if' conditions (1/2), 1 always True<br />
100% qualifiers (0/0)<br />
100% alternatives used (8/8)<br />
100% local declarations used (3/3)<br />
100% top-level declarations used (7/7)<br />
<br />
Sadly there is no documentation on how to exclude boolean coverage.<br />
<br />
== Hpc quirks ==<br />
<br />
Hpc (at least with 6.10.1) is not happy with literate haskell or with cpp. Even if your file contains no cpp, hpc will give spurious results if you use the cpp option on the command line. One way round both of these problems is to pre-process the source by hand with something like<br />
<br />
<nowiki>ghc -E -optP-P -cpp Foo.hs</nowiki><br />
<br />
and then remove the line<br />
<br />
<nowiki>{-# LINE 1 "Foo.hs" #-}</nowiki><br />
<br />
Don't use strip on your executables. I'm guessing hpc stashes information in the executable which strip removes.<br />
<br />
== Hpc with Cabal ==<br />
<br />
----<br />
<br />
We hope you find this tool-kit useful. If you have any comments or<br />
feedback, please feel free to email us.<br />
<br />
Andy Gill (andy@galois.com)<br />
Colin Runciman (colin@cs.york.ac.uk)</div>Ryantmhttps://wiki.haskell.org/index.php?title=Applications_and_libraries/Program_development&diff=58632Applications and libraries/Program development2014-08-03T22:55:17Z<p>Ryantm: /* Testing */ add hspec</p>
<hr />
<div>{{LibrariesPage}}<br />
<br />
A list of tools and libraries that are helpful when developing Haskell code.<br />
See also the [[Libraries and tools/Compiler tools|compiler tools]] and [[Libraries and tools/Theorem provers|theorem provers]].<br />
<br />
== Applications ==<br />
<br />
=== Preprocessors ===<br />
<br />
;[http://www.cs.york.ac.uk/fp/cpphs/ cpphs]<br />
:Cpphs is a re-implementation (in Haskell) of the C pre-processor.<br />
<br />
;[http://repetae.net/computer/haskell/DrIFT/ DrIFT]<br />
:DrIFT is a tool which allows derivation of instances for classes that aren't supported by the standard compilers. In addition, instances can be produced in seperate modules to that containing the type declaration. This allows instances to be derived for a type after the original module has been compiled. As a bonus, simple utility functions can also be produced from a type.<br />
<br />
;[[Applications and libraries/Generic programming/Strafunski|Strafunski]]<br />
:Strafunski is a Haskell bundle that provides support for generic programming in Haskell, based on the concept of a functional strategy. It consists of a combinator library (StrategyLib) and a precompiler (DrIFT-Strafunski).<br />
<br />
;[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/zeroth Zeroth]<br />
:A program using Template Haskell must link with the TH library even if it contains no references to TH after it has been compiled. Zeroth is a preprocessor which allows modules to use TH without linking with the TH library. To do this, Zeroth evaluates the top level splices from a module and saves the resulting code.<br />
<br />
;[http://www.cs.utah.edu/~hal/HAllInOne/index.html Haskell All-In-One]<br />
:Haskell All-In-One is a Haskell utility which will take a program implemented in multiple modules and convert it to a single module, for optimisation purposes.<br />
<br />
=== Build systems ===<br />
<br />
;[http://www.haskell.org/cabal Cabal]<br />
:The Haskell Cabal is a Common Architecture for Building Applications and Libraries. It is an API distributed with GHC, NHC98, and Hugs which allows a developer to easily group together a set of modules into a package. It is the standard build system for new Haskell libraries and applications <br />
<br />
;[http://www.cs.york.ac.uk/fp/hmake/ hmake], a Haskell-aware replacement for make<br />
:Automatically keeps track of module dependencies (i.e. no need to write any Makefiles!). Can be used with any of the usual Haskell compilers (ghc, hbc, nhc98).<br />
<br />
=== Source tags ===<br />
<br />
;[http://code.haskell.org/hasktags HaskTags]<br />
:Hasktags is a simple program that generates TAGS files for Haskell code. Together with a supporting editor (e.g. NEdit, XEmacs, or Vim) TAGS files can be used to quickly find the places where functions, data constructors etc. are defined.<br />
<br />
;[http://hackage.haskell.org/package/hothasktags HotHaskTags]<br />
:HotHaskTags is a reimplementation of HaskTags that is more aware of the structure of Haskell source. If you have multiple functions of the same name in a project and jump from a file, it will analyze the imports of that file (including qualified imports correctly) and jump to the one that is being referred to. Extended ctags format only (read: Vim only).<br />
<br />
;[http://kingfisher.nfshost.com/sw/gasbag/ gasbag]<br />
:Another reimplementation of hasktags which has a better understanding (than hasktags) of Haskell syntax. ctags files are generated in the traditional format only; where the same identifier is reused, gasbag attempts to determine the best one for inclusion in the ctags file.<br />
<br />
;[http://www.dtek.chalmers.se/~d99josve/tagsh.tar.gz tagsh]<br />
:A version of the tags program for Haskell. It uses the standardised hssource and posix library, works with GHC 5.02.1. tags file has been checked to work with vim and nedit.<br />
<br />
=== Program Transformation ===<br />
<br />
;[http://www.cs.kent.ac.uk/projects/refactor-fp/hare.html HaRe -- The Haskell Refactorer]<br />
:Mechanical refactoring of Haskell code (across module boundaries). HaRe now supports many refactorings such as renaming identifiers, moving/introducing/inlining definitions, and so on. Those refactorings are not limited to a single module. HaRe can be accessed from either Vim or Emacs<br />
<br />
;[http://www.cs.utah.edu/~hal/HAllInOne/ Haskell All-In-One]<br />
:This Haskell utility takes a program implemented in multiple modules and converts it to a single module. This way you get whole program optimization for compilers that do not support that. Resulting programs will be probably faster using this method.<br />
<br />
;[http://wiki.di.uminho.pt/wiki/bin/view/Alcino/DrHylo DrHylo]<br />
:Tool for deriving hylomorphisms from a restricted Haskell syntax. It is based on the algorithm first presented in the paper "Deriving Structural Hylomorphisms From Recursive Definitions" at ICFP'96 by Hu, Iwasaki, and Takeichi.<br />
<br />
;[http://community.haskell.org/~ndm/hlint/ HLint]<br />
:Tool for automatically suggesting program improvements - library functions you may have missed, instances of map or foldr etc.<br />
<br />
=== Documentation and browsing ===<br />
<br />
;[http://www.haskell.org/hoogle/ Hoogle]<br />
:Hoogle is a Haskell API search engine. It allows you to search for a function in the standard libraries by either name, or by approximate type signature.<br />
<br />
;[[Haddock]] A Haskell Documentation Tool<br />
:A tool for automatically generating documentation from annotated Haskell source code. It is primarily intended for documenting libraries, but it should be useful for any kind of Haskell code. Haddock lets you write documentation annotations next to the definitions of functions and types in the source code, in a syntax that is easy on the eye when writing the source code (no heavyweight mark-up). The documentation generated by Haddock is fully hyperlinked - click on a type name in a type signature to go straight to the definition, and documentation, for that type.<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/haskell/idoc/ IDoc] A No Frills Haskell Interface Documentation System<br />
:IDoc extracts interface documentation and declarations from Haskell modules based on standard Haskell layout rules and a small number of clues that the programmer embeds in interface comments. These clues have been designed to be visually non-imposing when displaying the source in a text editor. Interface documentation is rendered in standard markup languages (currently, only HTML is supported). IDoc has been designed to be simple to use and install.<br />
<br />
;[http://staff.fmi.uni-passau.de/~groessli/hdoc/ HDoc]<br />
:HDoc generates documentation in HTML format for Haskell modules. The generated documents are cross linked and include summaries and detailed descriptions for the documented functions, data types, type classes and instance declarations.<br />
<br />
;[http://www.ida.liu.se/~jakax/haskell.html HaskellDoc]<br />
:This program generates an HTML document showing the module interfaces of a Haskell project. Convenient links are placed for easy browsing of the different modules of the project, and for quick access to the source code.<br />
<br />
;[http://home.conceptsfa.nl/~jwit/HaSpell.html HaSpell]<br />
:HaSpell is a spelling and style checker for Haskell programs. It can detect spelling errors in comments in the program text, and optionally in the code itself. There is an option to detect metasyntactic variables (such as 'foo') and 'bad function prefixes' such as 'compute' and 'doThe' - these make the program less readable and generally indicate bad programming style.<br />
<br />
;[[Lambdabot]]<br />
:Lambdabot is a large, ad-hoc collection of Haskell development tools available for offline use. In particular, automatic point-free refactoring is available via a vim interface, as well as access to [[Hoogle]], djinn, ghci, and much much more.<br />
<br />
=== Tracing &amp; debugging ===<br />
<br />
Tracing gives access to otherwise invisible information about a computation. Conventional debuggers allow the user to step through the program computation, stop at given points and examine variable contents. This tracing method is quite unsuitable for Haskell, because its evaluation order is complex, function arguments are usually unwieldy large unevaluated expressions and generally<br />
computation details do not match the user's high-level view of functions mapping values to values. <br />
<br />
;[http://www.cs.mu.oz.au/~bjpop/buddha/ Buddha]<br />
:Buddha is a declarative debugger for Haskell 98 programs. It presents the evaluation of a Haskell program as a series of function applications. A typical debugging session involves a series of questions and answers. The questions are posed by the debugger, and the answers are provided by the user. The implementation of Buddha is based on program transformation.<br />
<br />
;[http://www.ida.liu.se/~henni Freja]<br />
:A compiler for a subset of Haskell. Running a compiled program creates an evaluation dependency tree as trace, a structure based on the idea of declarative debugging from the logic programming community. A debugging session consists of the user answering a sequence of yes/no questions.<br />
<br />
;[http://www.cs.york.ac.uk/fp/hat Hat]<br />
:A Haskell program is first transformed by hat-trans and then compiled with nhc98 or ghc. At runtime the program writes a trace file. There are tools for viewing the trace in various ways: Hat-stack shows a virtual stack of redexes. Hat-observe shows top-level functions in the style of Hood. Hat-trail enables exploring a computation backwards, starting from (part of) a faulty output or an error message. Hat-detect provides algorithmic debugging in the style of Freja. Hat-explore allows free navigation through a computation similar to traditional debuggers and algorithmic debugging and slicing.<br />
<br />
;[http://www.ittc.ku.edu/csdl/fpg/Tools/Hood Hood]<br />
:A library that permits to observe data structures at given program points. It can basically be used like print statements in imperative languages, but the lazy evaluation order is not affected and functions can be observed as well.<br />
<br />
;[http://community.haskell.org/~claus/GHood/ GHood]<br />
:"Graphical Hood" - a Java-based graphical observation event viewer, building on Hood.<br />
<br />
=== Revision control ===<br />
<br />
;[http://darcs.net Darcs]<br />
: Darcs is a cutting edge revision control system written in Haskell<br />
<br />
;[http://code.haskell.org/~dons/code/darcs-graph/ darcs-graph]<br />
:a tool for generating graphs of commit activity for darcs repositories.<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/haskell/VersionTool/ VersionTool]<br />
:a small utility that:<br />
* extracts version information from Cabal files,<br />
* maintains version tags in darcs,<br />
* computes patch levels by querying darcs,<br />
* extracts the current context from darcs, and<br />
* adds all this information to a source file<br />
<br />
;[http://hackage.haskell.org/package/hit Hit]<br />
: Git storage re-implementation in Haskell, allowing to read and write objects from a Haskell program easily.<br />
<br />
=== Licensing ===<br />
<br />
;[http://www.haskell.org/pipermail/haskell/2006-June/018043.html Kamiariduki]<br />
:a system to judge your derivative work's purpose and license is valid with Creative Commons License Works.<br />
<br />
=== Bug tracking ===<br />
<br />
;[http://urchin.earth.li/darcs/ian/bts/ Bark] <br />
:Bark is a bug tracking system written in Haskell<br />
<br />
=== Typesetting Haskell ===<br />
<br />
;[http://www.cs.york.ac.uk/fp/darcs/hscolour/ HsColour]<br />
:Colourise Haskell source code in HTML or ANSI terminal screen codes.<br />
<br />
;[http://people.cs.uu.nl/andres/lhs2tex/ lhs2tex]<br />
:A preprocessor for typesetting Haskell programs that combines some of the good features of pphs and smugweb. It generates LaTeX code from literate Haskell sources.<br />
<br />
;[http://www.cs.uu.nl/wiki/Ehc/Shuffle Shuffle]<br />
:Another tool helping literate programming in Haskell. It helps to maintain ''views'' in a literate programming project. For example, it is among the tools used for developing a compiler in an iterative way with manuals didactically reflecting these evolving series of versions deriving from the literal code (see [http://www.cs.uu.nl/wiki/Ehc/WebHome Essential Haskell Compiler] project). Thus, Shuffle gives us the possibility for making didactically the evolution of versions visible in the documentation, when this is needed. More generally, Shuffle gives us tangling and weaving possibilities of literate programming. I think it gives a way to think of literal program development in a more abstract way by supporting the concept of views (maybe a too far analogy: version control management -- e.g. [http://abridgegame.org/darcs/ darcs] -- helps thinking of program development in a more abstract way, too). Shuffle works well together with lhs2tex.<br />
<br />
;[http://web.comlab.ox.ac.uk/oucl/work/ian.lynagh/Haskell2LaTeX/ Haskell2Latex]<br />
:Ian Lynagh's Haskell2LaTeX takes a literate Haskell program, or any LaTeX document with embedded Haskell, and pretty-prints the Haskell sections within it. The most significant difference between Haskell2LaTeX and other programs with similar goals is is that Haskell2LaTeX parses the input rather than merely lexing it.<br />
<br />
==== TeX ====<br />
<br />
;[http://www.acooke.org/pancito-code/haskell.sty haskell.sty]<br />
:A Latex style file by Andrew Cooke that makes literal programming in Haskell simple.<br />
<br />
;[http://www.jantar.org/lambdatex lambdaTeX]<br />
:A TeX package for typesetting literate scripts in TeX. The output looks much like the code from Chris Okasaki's book "Purely Functional Data Structures", doing syntax highlighting and converting ASCII art such as <code>-&gt;</code> or <code>alpha</code> to proper mathematical symbols. It should work with both LaTeX and plain TeX, and it does its magic without any annotations, directly on the source code (lambdaTeX uses an almost-complete Haskell lexical analyzer written entirely in plain TeX). You only have to add <code>\input lambdaTeX</code> at the top of your source file, and manually typeset your literate comments so they look as good as the source code.<br />
<br />
;[http://www.cse.unsw.edu.au/~chak/haskell/haskell-style.html Haskell Style for LaTeX2e]<br />
:by Manuel Chakravarty provides environments and macros that simplify setting Haskell programs in LaTeX.<br />
<br />
== Editor support ==<br />
<br />
=== Integrated Development Environments ===<br />
<br />
See [[IDEs]].<br />
<br />
=== Editor modes ===<br />
<br />
''See [[IDEs#Vim]] and [[IDEs#Emacs]] for integration support of those editors.<br />
<br />
;[http://www.crimsoneditor.com/ Crimson Editor]<br />
:Free source code editor for MS Windows. Haskell support files are included in the standard installation, but must be added to the editor via the options dialog.<br />
<br />
;[http://kate-editor.org/ Kate]<br />
:Syntax highlighting files for KDE's Kate<br />
:* [https://github.com/zenzike/kate-haskel Files] by Nicolas Wu<br />
:* [http://www.informatik.uni-bonn.de/~ralf/software.html#syntax Files] by Ralf Hinze.<br />
:* [hs.xml hs.xml] and [lhs.xml lhs.xml] by Brian Huffman.<br />
<br />
;[http://www.nedit.org NEdit]<br />
:[http://www.nedit.org/ftp/contrib/highlighting/haskell.pats Syntax highlighting] and block comment support.<br />
<br />
;[http://www.textpad.com TextPad]<br />
:[http://www.haskell.org/libraries/Haskell98.syn Syntax highlighting file] by Jeroen van Wolffelaar and Arjan van IJzerdoorn, which inludes all prelude functions, datatype, constructors, etc, all in seperate groups.<br />
<br />
;[http://www.jedsoft.org/jed/ Jed]<br />
:[http://haskell.org/sitewiki/images/7/75/Haskellmode-jed.tgz Haskell mode] by Marcin 'Qrczak' Kowalczyk.<br />
<br />
;[http://www.codingmonkeys.de/subethaedit/ SubEthaEdit]<br />
:[http://www.codingmonkeys.de/subethaedit/modes.html Haskell mode For SubEthaEdit]<br />
<br />
;[http://developer.apple.com/technologies/tools/ Xcode]<br />
:[http://www.hoovy.org/HaskellXcodePlugin/ Xcode plugin] for enabling syntax highlighting, Xcode projects compiling and linking, and a couple missing features, for Haskell<br />
<br />
====Other====<br />
<br />
Some other, mostly obsolete, modes are available in [http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/CONTRIB/haskell-modes/ CVS].<br />
<br />
== Libraries ==<br />
<br />
=== Testing ===<br />
<br />
;[http://hunit.sourceforge.net HUnit]<br />
:A unit testing framework for Haskell, similar to JUnit for Java. With HUnit, the programmer can easily create tests, name them, group them into suites, and execute them, with the framework checking the results automatically. Test specification is concise, flexible, and convenient.<br />
<br />
;[http://www.cs.chalmers.se/~rjmh/QuickCheck/ QuickCheck]<br />
:A tool for testing Haskell programs automatically. The programmer provides a specification of the program, in the form of properties which functions should satisfy, and QuickCheck then tests that the properties hold in a large number of randomly generated cases. Specifications are expressed in Haskell, using combinators defined in the QuickCheck library. QuickCheck provides combinators to define properties, observe the distribution of test data, and define test data generators.<br />
<br />
;[http://www.informatik.uni-freiburg.de/~wehr/haskell/ HTF - The Haskell Test Framework]<br />
:The HTF lets you write HUnit tests and QuickCheck properties in an easy and convenient way. Additionally, the HTF provides a facility for testing programs by running them and comparing the actual output with the expected output (so called "file-based tests"). The HTF uses Template Haskell to collect all tests and properties, so you do not need to write boilerplate code for that purpose. Preprocessor macros provide you with file name and line number information for tests and properties that failed.<br />
<br />
;[https://github.com/hspec/hspec HSpec]<br />
:Hspec is a testing framework for Haskell. It is roughly based on the Ruby library RSpec. Some of Hspec's distinctive features are: a friendly DSL for defining tests, integration with QuickCheck, SmallCheck, and HUnit, parallel test execution, and automatic discovery of test files.<br />
<br />
;[http://projects.unsafeperformio.com/hpc/ Hpc: Haskell Program Coverage]<br />
:Hpc is a tool-kit to record and display [[Haskell program coverage]]. Hpc includes tools that instrument Haskell programs to record program coverage, run instrumented programs, and display the coverage information obtained.<br />
<br />
;[[Haskell Equational Reasoning Assistant]]<br />
:Functional programmers often appeal to equational reasoning to justify various decisions made in both design and implementation. This page introduces the Haskell Equational Reasoning Assistant (HERA), an architecture that provides both a GUI level and a batch level Haskell rewrite engine inside a single tool.<br />
<br />
;[http://www.cse.unsw.edu.au/~dons/pqc.html pQC: parallel QuickCheck]<br />
:pqc provides Test.QuickCheck.Parallel, a QuickCheck driver that runs jobs in parallel, and will utilise as many cores as you wish, with the SMP parallel GHC 6.6 runtime. It is simple, scalable replacement for Test.QuickCheck.Batch.<br />
<br />
=== Debugging ===<br />
<br />
;[http://www.cs.mu.oz.au/~bjpop/code.html highWaterMark]<br />
:A library for determining the amount of memory allocated at any point by a GHC program.<br />
<br />
;[http://www.cs.mu.oz.au/~bjpop/code.html GHC Internals library]<br />
:A GHC library for polymorphically deconstructing heap objects from within Haskell code.<br />
<br />
;[http://www.cs.mu.oz.au/~bjpop/code.html GHC Heap and Stable Table Printing library]<br />
:Two libraries for GHC. The first is for printing heap objects from within Haskell or C code. The second is for dumping the contents of the Stable Table which is used for Stable Pointers and Stable Names.<br />
<br />
;[http://www.cse.unsw.edu.au/~dons/loch.html LocH]<br />
:Located errors, tracing and exceptions in Haskell.<br />
<br />
=== Formal methods ===<br />
<br />
;[http://aprove.informatik.rwth-aachen.de Haskell98 termination analyzer]<br />
:Checks termination of given start terms w.r.t. a Haskell program:<br />
* [[Analysis and design|analysis and design methods]]<br />
* [[Libraries and tools/Theorem provers|theorem provers]].</div>Ryantm