X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdocs%2Fusers_guide%2Fglasgow_exts.xml;h=9e712f8aaa3745f08bfdf07a506f017c2a25516d;hb=10aa5c536b19b85ef5a8ddca451ccb64e45fc5e5;hp=3d523998d1c117f402357e45c17a8452eae6d39e;hpb=d9bc4e4a3372c732c1c631d8dae7e5613d7464fe;p=ghc-hetmet.git diff --git a/ghc/docs/users_guide/glasgow_exts.xml b/ghc/docs/users_guide/glasgow_exts.xml index 3d52399..9e712f8 100644 --- a/ghc/docs/users_guide/glasgow_exts.xml +++ b/ghc/docs/users_guide/glasgow_exts.xml @@ -1427,7 +1427,7 @@ declarations. Define your own instances! This section documents GHC's implementation of multi-parameter type classes. There's lots of background in the paper Type +url="http://research.microsoft.com/~simonpj/Papers/type-class-design-space" >Type classes: exploring the design space (Simon Peyton Jones, Mark Jones, Erik Meijer). @@ -1762,7 +1762,8 @@ these declarations: instance context3 => C Int [a] where ... -- (C) instance context4 => C Int [Int] where ... -- (D) -The instances (A) and (B) match the constraint C Int Bool, but (C) and (D) do not. When matching, GHC takes +The instances (A) and (B) match the constraint C Int Bool, +but (C) and (D) do not. When matching, GHC takes no account of the context of the instance declaration (context1 etc). GHC's default behaviour is that exactly one instance must match the @@ -1795,10 +1796,34 @@ GHC will instead pick (C), without complaining about the problem of subsequent instantiations. -Because overlaps are checked and reported lazily, as described above, you need -the in the module that calls -the overloaded function, rather than in the module that defines it. - +The willingness to be overlapped or incoherent is a property of +the instance declaration itself, controlled by the +presence or otherwise of the +and flags when that mdodule is +being defined. Neither flag is required in a module that imports and uses the +instance declaration. Specifically, during the lookup process: + + +An instance declaration is ignored during the lookup process if (a) a more specific +match is found, and (b) the instance declaration was compiled with +. The flag setting for the +more-specific instance does not matter. + + +Suppose an instance declaration does not matche the constraint being looked up, but +does unify with it, so that it might match when the constraint is further +instantiated. Usually GHC will regard this as a reason for not committing to +some other constraint. But if the instance declaration was compiled with +, GHC will skip the "does-it-unify?" +check for that declaration. + + +All this makes it possible for a library author to design a library that relies on +overlapping instances without the library client having to know. + +The flag implies the + flag, but not vice versa. + @@ -3388,6 +3413,68 @@ the standard method is used or the one described here.) + +Generalised typing of mutually recursive bindings + + +The Haskell Report specifies that a group of bindings (at top level, or in a +let or where) should be sorted into +strongly-connected components, and then type-checked in dependency order +(Haskell +Report, Section 4.5.1). +As each group is type-checked, any binders of the group that +have +an explicit type signature are put in the type environment with the specified +polymorphic type, +and all others are monomorphic until the group is generalised +(Haskell Report, Section 4.5.2). + + +Following a suggestion of Mark Jones, in his paper +Typing Haskell in +Haskell, +GHC implements a more general scheme. If is +specified: +the dependency analysis ignores references to variables that have an explicit +type signature. +As a result of this refined dependency analysis, the dependency groups are smaller, and more bindings will +typecheck. For example, consider: + + f :: Eq a => a -> Bool + f x = (x == x) || g True || g "Yes" + + g y = (y <= y) || f True + +This is rejected by Haskell 98, but under Jones's scheme the definition for +g is typechecked first, separately from that for +f, +because the reference to f in g's right +hand side is ingored by the dependency analysis. Then g's +type is generalised, to get + + g :: Ord a => a -> Bool + +Now, the defintion for f is typechecked, with this type for +g in the type environment. + + + +The same refined dependency analysis also allows the type signatures of +mutually-recursive functions to have different contexts, something that is illegal in +Haskell 98 (Section 4.5.2, last sentence). With + +GHC only insists that the type signatures of a refined group have identical +type signatures; in practice this means that only variables bound by the same +pattern binding must have the same context. For example, this is fine: + + f :: Eq a => a -> Bool + f x = (x == x) || g True + + g :: Ord a => a -> Bool + g y = (y <= y) || f True + + + @@ -3448,9 +3535,10 @@ type above, the type of each constructor must end with ... -> Term ... -You cannot use a deriving clause on a GADT-style data type declaration, -nor can you use record syntax. (It's not clear what these constructs would mean. For example, -the record selectors might ill-typed.) However, you can use strictness annotations, in the obvious places +You cannot use record syntax on a GADT-style data type declaration. ( +It's not clear what these it would mean. For example, +the record selectors might ill-typed.) +However, you can use strictness annotations, in the obvious places in the constructor type: data Term a where @@ -3461,6 +3549,23 @@ in the constructor type: +You can use a deriving clause on a GADT-style data type +declaration, but only if the data type could also have been declared in +Haskell-98 syntax. For example, these two declarations are equivalent + + data Maybe1 a where { + Nothing1 :: Maybe a ; + Just1 :: a -> Maybe a + } deriving( Eq, Ord ) + + data Maybe2 a = Nothing2 | Just2 a + deriving( Eq, Ord ) + +This simply allows you to declare a vanilla Haskell-98 data type using the +where form without losing the deriving clause. + + + Pattern matching causes type refinement. For example, in the right hand side of the equation eval :: Term a -> a @@ -3544,9 +3649,11 @@ Tim Sheard is going to expand it.) A splice can occur in place of - an expression; the spliced expression must have type Expr + an expression; the spliced expression must + have type Q Exp a list of top-level declarations; ; the spliced expression must have type Q [Dec] - a type; the spliced expression must have type Type. + [Planned, but not implemented yet.] a + type; the spliced expression must have type Q Typ. (Note that the syntax for a declaration splice uses "$" not "splice" as in the paper. Also the type of the enclosed expression must be Q [Dec], not [Q Dec] @@ -3561,7 +3668,7 @@ Tim Sheard is going to expand it.) the quotation has type Expr. [d| ... |], where the "..." is a list of top-level declarations; the quotation has type Q [Dec]. - [t| ... |], where the "..." is a type; + [Planned, but not implemented yet.] [t| ... |], where the "..." is a type; the quotation has type Type. @@ -4306,7 +4413,7 @@ Assertion failures can be caught, see the documentation for the - You can deprecate a function, class, or type, with the + You can deprecate a function, class, type, or data constructor, with the following top-level declaration: {-# DEPRECATED f, C, T "Don't use these" #-} @@ -4314,6 +4421,13 @@ Assertion failures can be caught, see the documentation for the When you compile any module that imports and uses any of the specified entities, GHC will print the specified message. + You can only depecate entities declared at top level in the module + being compiled, and you can only use unqualified names in the list of + entities being deprecated. A capitalised name, such as T + refers to either the type constructor T + or the data constructor T, or both if + both are in scope. If both are in scope, there is currently no way to deprecate + one without the other (c.f. fixities ). Any use of the deprecated item, or of anything from a deprecated @@ -4562,7 +4676,7 @@ key_function :: Int -> String -> (Bool, Double) overloaded function: -hammeredLookup :: Ord key => [(key, value)] -> key -> value + hammeredLookup :: Ord key => [(key, value)] -> key -> value If it is heavily used on lists with @@ -4570,7 +4684,7 @@ hammeredLookup :: Ord key => [(key, value)] -> key -> value follows: -{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-} + {-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-} A SPECIALIZE pragma for a function can @@ -4581,7 +4695,35 @@ hammeredLookup :: Ord key => [(key, value)] -> key -> value (see ) that rewrites a call to the un-specialised function into a call to the specialised one. - In earlier versions of GHC, it was possible to provide your own + The type in a SPECIALIZE pragma can be any type that is less + polymorphic than the type of the original function. In concrete terms, + if the original function is f then the pragma + + {-# SPECIALIZE f :: <type> #-} + + is valid if and only if the defintion + + f_spec :: <type> + f_spec = f + + is valid. Here are some examples (where we only give the type signature + for the original function, not its code): + + f :: Eq a => a -> b -> b + {-# SPECIALISE g :: Int -> b -> b #-} + + g :: (Eq a, Ix b) => a -> b -> b + {-# SPECIALISE g :: (Eq a) => a -> Int -> Int #-} + + h :: Eq a => a -> a -> a + {-# SPECIALISE h :: (Eq a) => [a] -> [a] -> [a] #-} + +The last of these examples will generate a +RULE with a somewhat-complex left-hand side (try it yourself), so it might not fire very +well. If you use this kind of specialisation, let us know how well it works. + + + Note: In earlier versions of GHC, it was possible to provide your own specialised function for a given type: