+ <!-- ===================== View patterns =================== -->
+
+<sect2 id="view-patterns">
+<title>View patterns
+</title>
+
+<para>
+View patterns are enabled by the flag <literal>-XViewPatterns</literal>.
+More information and examples of view patterns can be found on the
+<ulink url="http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns">Wiki
+page</ulink>.
+</para>
+
+<para>
+View patterns are somewhat like pattern guards that can be nested inside
+of other patterns. They are a convenient way of pattern-matching
+against values of abstract types. For example, in a programming language
+implementation, we might represent the syntax of the types of the
+language as follows:
+
+<programlisting>
+type Typ
+
+data TypView = Unit
+ | Arrow Typ Typ
+
+view :: Type -> TypeView
+
+-- additional operations for constructing Typ's ...
+</programlisting>
+
+The representation of Typ is held abstract, permitting implementations
+to use a fancy representation (e.g., hash-consing to manage sharing).
+
+Without view patterns, using this signature a little inconvenient:
+<programlisting>
+size :: Typ -> Integer
+size t = case view t of
+ Unit -> 1
+ Arrow t1 t2 -> size t1 + size t2
+</programlisting>
+
+It is necessary to iterate the case, rather than using an equational
+function definition. And the situation is even worse when the matching
+against <literal>t</literal> is buried deep inside another pattern.
+</para>
+
+<para>
+View patterns permit calling the view function inside the pattern and
+matching against the result:
+<programlisting>
+size (view -> Unit) = 1
+size (view -> Arrow t1 t2) = size t1 + size t2
+</programlisting>
+
+That is, we add a new form of pattern, written
+<replaceable>expression</replaceable> <literal>-></literal>
+<replaceable>pattern</replaceable> that means "apply the expression to
+whatever we're trying to match against, and then match the result of
+that application against the pattern". The expression can be any Haskell
+expression of function type, and view patterns can be used wherever
+patterns are used.
+</para>
+
+<para>
+The semantics of a pattern <literal>(</literal>
+<replaceable>exp</replaceable> <literal>-></literal>
+<replaceable>pat</replaceable> <literal>)</literal> are as follows:
+
+<itemizedlist>
+
+<listitem> Scoping:
+
+<para>The variables bound by the view pattern are the variables bound by
+<replaceable>pat</replaceable>.
+</para>
+
+<para>
+Any variables in <replaceable>exp</replaceable> are bound occurrences,
+but variables bound "to the left" in a pattern are in scope. This
+feature permits, for example, one argument to a function to be used in
+the view of another argument. For example, the function
+<literal>clunky</literal> from <xref linkend="pattern-guards" /> can be
+written using view patterns as follows:
+
+<programlisting>
+clunky env (lookup env -> Just val1) (lookup env -> Just val2) = val1 + val2
+...other equations for clunky...
+</programlisting>
+</para>
+
+<para>
+More precisely, the scoping rules are:
+<itemizedlist>
+<listitem>
+<para>
+In a single pattern, variables bound by patterns to the left of a view
+pattern expression are in scope. For example:
+<programlisting>
+example :: Maybe ((String -> Integer,Integer), String) -> Bool
+example Just ((f,_), f -> 4) = True
+</programlisting>
+
+Additionally, in function definitions, variables bound by matching earlier curried
+arguments may be used in view pattern expressions in later arguments:
+<programlisting>
+example :: (String -> Integer) -> String -> Bool
+example f (f -> 4) = True
+</programlisting>
+That is, the scoping is the same as it would be if the curried arguments
+were collected into a tuple.
+</para>
+</listitem>
+
+<listitem>
+<para>
+In mutually recursive bindings, such as <literal>let</literal>,
+<literal>where</literal>, or the top level, view patterns in one
+declaration may not mention variables bound by other declarations. That
+is, each declaration must be self-contained. For example, the following
+program is not allowed:
+<programlisting>
+let {(x -> y) = e1 ;
+ (y -> x) = e2 } in x
+</programlisting>
+
+(We may lift this
+restriction in the future; the only cost is that type checking patterns
+would get a little more complicated.)
+
+
+</para>
+</listitem>
+</itemizedlist>
+
+</para>
+</listitem>
+
+<listitem><para> Typing: If <replaceable>exp</replaceable> has type
+<replaceable>T1</replaceable> <literal>-></literal>
+<replaceable>T2</replaceable> and <replaceable>pat</replaceable> matches
+a <replaceable>T2</replaceable>, then the whole view pattern matches a
+<replaceable>T1</replaceable>.
+</para></listitem>
+
+<listitem><para> Matching: To the equations in Section 3.17.3 of the
+<ulink url="http://www.haskell.org/onlinereport/">Haskell 98
+Report</ulink>, add the following:
+<programlisting>
+case v of { (e -> p) -> e1 ; _ -> e2 }
+ =
+case (e v) of { p -> e1 ; _ -> e2 }
+</programlisting>
+That is, to match a variable <replaceable>v</replaceable> against a pattern
+<literal>(</literal> <replaceable>exp</replaceable>
+<literal>-></literal> <replaceable>pat</replaceable>
+<literal>)</literal>, evaluate <literal>(</literal>
+<replaceable>exp</replaceable> <replaceable> v</replaceable>
+<literal>)</literal> and match the result against
+<replaceable>pat</replaceable>.
+</para></listitem>
+
+<listitem><para> Efficiency: When the same view function is applied in
+multiple branches of a function definition or a case expression (e.g.,
+in <literal>size</literal> above), GHC makes an attempt to collect these
+applications into a single nested case expression, so that the view
+function is only applied once. Pattern compilation in GHC follows the
+matrix algorithm described in Chapter 4 of <ulink
+url="http://research.microsoft.com/~simonpj/Papers/slpj-book-1987/">The
+Implementation of Functional Programming Languages</ulink>. When the
+top rows of the first column of a matrix are all view patterns with the
+"same" expression, these patterns are transformed into a single nested
+case. This includes, for example, adjacent view patterns that line up
+in a tuple, as in
+<programlisting>
+f ((view -> A, p1), p2) = e1
+f ((view -> B, p3), p4) = e2
+</programlisting>
+</para>
+
+<para> The current notion of when two view pattern expressions are "the
+same" is very restricted: it is not even full syntactic equality.
+However, it does include variables, literals, applications, and tuples;
+e.g., two instances of <literal>view ("hi", "there")</literal> will be
+collected. However, the current implementation does not compare up to
+alpha-equivalence, so two instances of <literal>(x, view x ->
+y)</literal> will not be coalesced.
+</para>
+
+</listitem>
+
+</itemizedlist>
+</para>
+
+</sect2>
+