diff options
author | simonpj <unknown> | 2003-02-14 14:18:02 +0000 |
---|---|---|
committer | simonpj <unknown> | 2003-02-14 14:18:02 +0000 |
commit | db48bcb95d2812759285177bb5ddadd812ac2724 (patch) | |
tree | 9d4f381e34b65dd2328b0c0d187a5ded0243c1af | |
parent | cbafa79d42c8e5d2099bd314701166065619e873 (diff) | |
download | haskell-db48bcb95d2812759285177bb5ddadd812ac2724.tar.gz |
[project @ 2003-02-14 14:18:02 by simonpj]
A bit more about scoped type variables
-rw-r--r-- | ghc/docs/users_guide/glasgow_exts.sgml | 98 |
1 files changed, 55 insertions, 43 deletions
diff --git a/ghc/docs/users_guide/glasgow_exts.sgml b/ghc/docs/users_guide/glasgow_exts.sgml index bf7779602c..2d53f08cc1 100644 --- a/ghc/docs/users_guide/glasgow_exts.sgml +++ b/ghc/docs/users_guide/glasgow_exts.sgml @@ -2870,49 +2870,6 @@ scope over the methods defined in the <literal>where</literal> part. For exampl </sect3> <sect3> -<title>Result type signatures</title> - -<para> - -<itemizedlist> -<listitem> - -<para> - The result type of a function can be given a signature, -thus: - - -<programlisting> - f (x::a) :: [a] = [x,x,x] -</programlisting> - - -The final <literal>:: [a]</literal> after all the patterns gives a signature to the -result type. Sometimes this is the only way of naming the type variable -you want: - - -<programlisting> - f :: Int -> [a] -> [a] - f n :: ([a] -> [a]) = let g (x::a, y::a) = (y,x) - in \xs -> map g (reverse xs `zip` xs) -</programlisting> - - -</para> -</listitem> - -</itemizedlist> - -</para> - -<para> -Result type signatures are not yet implemented in Hugs. -</para> - -</sect3> - -<sect3> <title>Where a pattern type signature can occur</title> <para> @@ -3025,6 +2982,61 @@ in <literal>f4</literal>'s scope. </para> </sect3> + +<sect3> +<title>Result type signatures</title> + +<para> +The result type of a function can be given a signature, thus: + + +<programlisting> + f (x::a) :: [a] = [x,x,x] +</programlisting> + + +The final <literal>:: [a]</literal> after all the patterns gives a signature to the +result type. Sometimes this is the only way of naming the type variable +you want: + + +<programlisting> + f :: Int -> [a] -> [a] + f n :: ([a] -> [a]) = let g (x::a, y::a) = (y,x) + in \xs -> map g (reverse xs `zip` xs) +</programlisting> + +</para> +<para> +The type variables bound in a result type signature scope over the right hand side +of the definition. However, consider this corner-case: +<programlisting> + rev1 :: [a] -> [a] = \xs -> reverse xs + + foo ys = rev (ys::[a]) +</programlisting> +The signature on <literal>rev1</literal> is considered a pattern type signature, not a result +type signature, and the type variables it binds have the same scope as <literal>rev1</literal> +itself (i.e. the right-hand side of <literal>rev1</literal> and the rest of the module too). +In particular, the expression <literal>(ys::[a])</literal> is OK, because the type variable <literal>a</literal> +is in scope (otherwise it would mean <literal>(ys::forall a.[a])</literal>, which would be rejected). +</para> +<para> +As mentioned above, <literal>rev1</literal> is made monomorphic by this scoping rule. +For example, the following program would be rejected, because it claims that <literal>rev1</literal> +is polymorphic: +<programlisting> + rev1 :: [b] -> [b] + rev1 :: [a] -> [a] = \xs -> reverse xs +</programlisting> +</para> + +<para> +Result type signatures are not yet implemented in Hugs. +</para> + +</sect3> + </sect2> <sect2 id="newtype-deriving"> |