X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdocs%2Fusers_guide%2Fglasgow_exts.xml;h=a5ac2b3b9784bcfd64cef599324e65690ced9ebb;hb=59c9c122f942f348008d4ed8ba088286343d63d3;hp=620f8b68ecc27f35ba7cf96ffa9fd4ba5edf7223;hpb=8b3ccdc9c224207df38821681c46cfd73d81081b;p=ghc-hetmet.git
diff --git a/ghc/docs/users_guide/glasgow_exts.xml b/ghc/docs/users_guide/glasgow_exts.xml
index 620f8b6..a5ac2b3 100644
--- a/ghc/docs/users_guide/glasgow_exts.xml
+++ b/ghc/docs/users_guide/glasgow_exts.xml
@@ -1673,38 +1673,124 @@ class like this:
Instance declarations
-
-Instance heads
+
+Relaxed rules for instance declarations
+
+An instance declaration has the form
+
+ instance ( assertion1, ..., assertionn) => classtype1 ... typem where ...
+
+The part before the "=>" is the
+context, while the part after the
+"=>" is the head of the instance declaration.
+
-The head of an instance declaration is the part to the
-right of the "=>". In Haskell 98 the head of an instance
-declaration
+In Haskell 98 the head of an instance declaration
must be of the form C (T a1 ... an), where
C is the class, T is a type constructor,
and the a1 ... an are distinct type variables.
+Furthermore, the assertions in the context of the instance declaration be of
+the form C a where a is a type variable.
-The flag lifts this restriction and allows the
-instance head to be of form C t1 ... tn where t1
-... tn are arbitrary types (provided, of course, everything is
-well-kinded). In particular, types ti can be type variables
-or structured types, and can contain repeated occurrences of a single type
-variable.
-Examples:
+The flag loosens these restrictions
+considerably. Firstly, multi-parameter type classes are permitted. Secondly,
+the context and head of the instance declaration can each consist of arbitrary
+(well-kinded) assertions (C t1 ... tn) subject only to the following rule:
+for each assertion in the context
+
+No type variable has more occurrences in the assertion than in the head
+Tthe assertion has fewer constructors and variables (taken together
+ and counting repetitions) than the head
+
+These restrictions ensure that context reduction terminates: each reduction
+step makes the problem smaller
+constructor. For example, the following would make the type checker
+loop if it wasn't excluded:
+
+ instance C a => C a where ...
+
+For example, these are OK:
- instance Eq (T a a) where ...
- -- Repeated type variable
+ instance C Int [a] -- Multiple parameters
+ instance Eq (S [a]) -- Structured type in head
- instance Eq (S [a]) where ...
- -- Structured type
+ -- Repeated type variable in head
+ instance C4 a a => C4 [a] [a]
+ instance Stateful (ST s) (MutVar s)
- instance C Int [a] where ...
- -- Multiple parameters
+ -- Head can consist of type variables only
+ instance C a
+ instance (Eq a, Show b) => C2 a b
+
+ -- Non-type variables in context
+ instance Show (s a) => Show (Sized s a)
+ instance C2 Int a => C3 Bool [a]
+ instance C2 Int a => C3 [a] b
+
+But these are not:
+
+ instance C a => C a where ...
+ -- Context assertion no smaller than head
+ instance C b b => Foo [b] where ...
+ -- (C b b) has more more occurrences of b than the head
+
+
+A couple of useful idioms are these. First,
+if one allows overlapping instance declarations then it's quite
+convenient to have a "default instance" declaration that applies if
+something more specific does not:
+
+ instance C a where
+ op = ... -- Default
+
+
+Second, sometimes you might want to use the following to get the
+effect of a "class synonym":
+
+
+
+ class (C1 a, C2 a, C3 a) => C a where { }
+
+ instance (C1 a, C2 a, C3 a) => C a where { }
+
+This allows you to write shorter signatures:
+
+
+ f :: C a => ...
+
+instead of
+
+ f :: (C1 a, C2 a, C3 a) => ...
+
+
+
+
+
+Undecidable instances
+
+
+Sometimes even the rules of are too onerous.
+Voluminous correspondence on the Haskell mailing list has convinced me
+that it's worth experimenting with more liberal rules. If you use
+the experimental flag
+-fallow-undecidable-instances
+option, you can use arbitrary
+types in both an instance context and instance head. Termination is ensured by having a
+fixed-depth recursion stack. If you exceed the stack depth you get a
+sort of backtrace, and the opportunity to increase the stack depth
+with N.
+
+
+I'm on the lookout for a less brutal solution: a simple rule that preserves decidability while
+allowing these idioms interesting idioms.
+
+
Overlapping instances
@@ -1835,112 +1921,6 @@ reversed, but it makes sense to me.
-
-Undecidable instances
-
-An instance declaration must normally obey the following rules:
-
-At least one of the types in the head of
-an instance declaration must not be a type variable.
-For example, these are OK:
-
-
- instance C Int a where ...
-
- instance D (Int, Int) where ...
-
- instance E [[a]] where ...
-
-but this is not:
-
- instance F a where ...
-
-Note that instance heads may contain repeated type variables ().
-For example, this is OK:
-
- instance Stateful (ST s) (MutVar s) where ...
-
-
-
-
-
-
-All of the types in the context of
-an instance declaration must be type variables.
-Thus
-
-instance C a b => Eq (a,b) where ...
-
-is OK, but
-
-instance C Int b => Foo b where ...
-
-is not OK.
-
-
-
-These restrictions ensure that
-context reduction terminates: each reduction step removes one type
-constructor. For example, the following would make the type checker
-loop if it wasn't excluded:
-
- instance C a => C a where ...
-
-There are two situations in which the rule is a bit of a pain. First,
-if one allows overlapping instance declarations then it's quite
-convenient to have a "default instance" declaration that applies if
-something more specific does not:
-
-
-
- instance C a where
- op = ... -- Default
-
-
-
-Second, sometimes you might want to use the following to get the
-effect of a "class synonym":
-
-
-
- class (C1 a, C2 a, C3 a) => C a where { }
-
- instance (C1 a, C2 a, C3 a) => C a where { }
-
-
-
-This allows you to write shorter signatures:
-
-
-
- f :: C a => ...
-
-
-
-instead of
-
-
-
- f :: (C1 a, C2 a, C3 a) => ...
-
-
-
-Voluminous correspondence on the Haskell mailing list has convinced me
-that it's worth experimenting with more liberal rules. If you use
-the experimental flag
--fallow-undecidable-instances
-option, you can use arbitrary
-types in both an instance context and instance head. Termination is ensured by having a
-fixed-depth recursion stack. If you exceed the stack depth you get a
-sort of backtrace, and the opportunity to increase the stack depth
-with N.
-
-
-I'm on the lookout for a less brutal solution: a simple rule that preserves decidability while
-allowing these idioms interesting idioms.
-
-
-
@@ -4902,7 +4882,7 @@ key_function :: Int -> String -> (Bool, Double)
for the original function, not its code):
f :: Eq a => a -> b -> b
- {-# SPECIALISE g :: Int -> b -> b #-}
+ {-# SPECIALISE f :: Int -> b -> b #-}
g :: (Eq a, Ix b) => a -> b -> b
{-# SPECIALISE g :: (Eq a) => a -> Int -> Int #-}
@@ -4915,6 +4895,35 @@ RULE with a somewhat-complex left-hand side (try it yourself), so it might not f
well. If you use this kind of specialisation, let us know how well it works.
+A SPECIALIZE pragma can optionally be followed with a
+INLINE or NOINLINE pragma, optionally
+followed by a phase, as described in .
+The INLINE pragma affects the specialised verison of the
+function (only), and applies even if the function is recursive. The motivating
+example is this:
+
+-- A GADT for arrays with type-indexed representation
+data Arr e where
+ ArrInt :: !Int -> ByteArray# -> Arr Int
+ ArrPair :: !Int -> Arr e1 -> Arr e2 -> Arr (e1, e2)
+
+(!:) :: Arr e -> Int -> e
+{-# SPECIALISE INLINE (!:) :: Arr Int -> Int -> Int #-}
+{-# SPECIALISE INLINE (!:) :: Arr (a, b) -> Int -> (a, b) #-}
+(ArrInt _ ba) !: (I# i) = I# (indexIntArray# ba i)
+(ArrPair _ a1 a2) !: i = (a1 !: i, a2 !: i)
+
+Here, (!:) is a recursive function that indexes arrays
+of type Arr e. Consider a call to (!:)
+at type (Int,Int). The second specialisation will fire, and
+the specialised function will be inlined. It has two calls to
+(!:),
+both at type Int. Both these calls fire the first
+specialisation, whose body is also inlined. The result is a type-based
+unrolling of the indexing function.
+Warning: you can make GHC diverge by using SPECIALISE INLINE
+on an ordinarily-recursive function.
+
Note: In earlier versions of GHC, it was possible to provide your own
specialised function for a given type: