| | 1 | |
| | 2 | == Changes to Template Haskell Library == |
| | 3 | |
| | 4 | Throughout this document, it is assumed that the current version of GHC is 7.4.1. |
| | 5 | |
| | 6 | A proposed change will add the following constructors to TH's {{{Type}}} datatype... |
| | 7 | |
| | 8 | {{{ |
| | 9 | | PromotedListT [Type] -- for types of the form '[Int, Bool] |
| | 10 | | PromotedTupleT [Type] -- for types of the form '(Int, 'False) |
| | 11 | | PromotedConsT -- ': |
| | 12 | }}} |
| | 13 | |
| | 14 | ... and the following constructors to TH's {{{Kind}}} datatype: |
| | 15 | |
| | 16 | {{{ |
| | 17 | | ConK Name -- for kinds of the form Bool |
| | 18 | | VarK Name -- k |
| | 19 | | AppK Kind Kind -- k1 k2 |
| | 20 | | ListK -- [] |
| | 21 | | TupleK Int -- (), (,), ... |
| | 22 | | ConstraintK -- Constraint |
| | 23 | }}} |
| | 24 | |
| | 25 | Note that there is no {{{ForallK}}} constructor because the internal GHC representation for kinds with variables does not use this. Kinds are automatically generalized over an entire type expression. |
| | 26 | |
| | 27 | TH will also need to support promoted constructors other than lists and tuples, but this is in fact already supported through the use of {{{ConT}}}. The namespace of defined types and of promoted types is also already kept distinct. For example, if we have the definition {{{data Foo = Foo}}}, the results of {{{ [t| Foo |] }}} and {{{ [t| 'Foo |] }}} are distinct (as in, {{{==}}} returns {{{False}}}). However, applying {{{show}}} to these two results produces the same string. Using the naming quote syntax, we can access promoted data constructors using the single-quote form. For example, {{{ConT 'False}}} denotes the promoted data constructor {{{'False}}}. (Note that the parsed interpretations of the {{{'}}} in these two snippets are entirely unrelated.) |
| | 28 | |
| | 29 | == Alternatives == |
| | 30 | |
| | 31 | Here are two alternatives to the above changes. They are orthogonal to each other (i.e. either can be chosen without affecting whether or not the other is chosen). |
| | 32 | |
| | 33 | === Simpler Types === |
| | 34 | |
| | 35 | Instead of the new types above, we could have the following: |
| | 36 | |
| | 37 | {{{ |
| | 38 | | PromotedTupleT Int -- '(), '(,), ... |
| | 39 | | PromotedNilT -- '[] |
| | 40 | | PromotedConsT -- ': |
| | 41 | }}} |
| | 42 | |
| | 43 | Client code could create full tuples and lists using a combination of the above constructors with a liberal sprinkling of {{{AppT}}}s. |
| | 44 | * Pros: Matches syntax of existing {{{TupleT}}} and {{{ListT}}}. For lists, matches forms available in surface syntax. |
| | 45 | * Cons: Believed to be harder to use in practice. The {{{PromotedTupleT}}} construct here is not available in surface syntax. This also loses the ability to write succinct lists, while the original format proposed above allows for nil as a 0-element list. |
| | 46 | |
| | 47 | It may be worth noting that {{{'(,) Int Bool}}} is ''not'' a synonym for {{{'(Int,Bool)}}}. {{{'(,) Int Bool}}} is a parse error. |
| | 48 | |
| | 49 | === Structured Kinds === |
| | 50 | |
| | 51 | Instead of the new {{{ListK}}} and {{{TupleK}}} kinds above, we could have the following: |
| | 52 | |
| | 53 | {{{ |
| | 54 | | ListK Kind -- [k] |
| | 55 | | TupleK [Kind] -- (k1,k2,...) |
| | 56 | }}} |
| | 57 | |
| | 58 | * Pros: Perhaps easier to use. Mirrors surface syntax. |
| | 59 | * Cons: Does not match internal GHC representation, including what is printed in error messages and such. Different from the way {{{Type}}} works. |
| | 60 | |
| | 61 | It may be worth noting that, in the kind language, {{{(,) Int Bool}}} is ''not'' a synonym for {{{(Int,Bool)}}}. {{{(,) Int Bool}}} is a parse error. |