[[project @ 2003-02-14 14:18:02 by simonpj] simonpj**20030214141802 A bit more about scoped type variables ] { hunk ./ghc/docs/users_guide/glasgow_exts.sgml 2872 - -Result type signatures - - - - - - - - The result type of a function can be given a signature, -thus: - - - - f (x::a) :: [a] = [x,x,x] - - - -The final :: [a] after all the patterns gives a signature to the -result type. Sometimes this is the only way of naming the type variable -you want: - - - - f :: Int -> [a] -> [a] - f n :: ([a] -> [a]) = let g (x::a, y::a) = (y,x) - in \xs -> map g (reverse xs `zip` xs) - - - - - - - - - - - -Result type signatures are not yet implemented in Hugs. - - - - hunk ./ghc/docs/users_guide/glasgow_exts.sgml 2985 + + +Result type signatures + + +The result type of a function can be given a signature, thus: + + + + f (x::a) :: [a] = [x,x,x] + + + +The final :: [a] after all the patterns gives a signature to the +result type. Sometimes this is the only way of naming the type variable +you want: + + + + f :: Int -> [a] -> [a] + f n :: ([a] -> [a]) = let g (x::a, y::a) = (y,x) + in \xs -> map g (reverse xs `zip` xs) + + + + +The type variables bound in a result type signature scope over the right hand side +of the definition. However, consider this corner-case: + + rev1 :: [a] -> [a] = \xs -> reverse xs + + foo ys = rev (ys::[a]) + +The signature on rev1 is considered a pattern type signature, not a result +type signature, and the type variables it binds have the same scope as rev1 +itself (i.e. the right-hand side of rev1 and the rest of the module too). +In particular, the expression (ys::[a]) is OK, because the type variable a +is in scope (otherwise it would mean (ys::forall a.[a]), which would be rejected). + + +As mentioned above, rev1 is made monomorphic by this scoping rule. +For example, the following program would be rejected, because it claims that rev1 +is polymorphic: + + rev1 :: [b] -> [b] + rev1 :: [a] -> [a] = \xs -> reverse xs + + + + +Result type signatures are not yet implemented in Hugs. + + + + }