Commit 276da792 authored by Simon Peyton Jones's avatar Simon Peyton Jones

Improve error message on typed holes, and user manual (Tradc #10040)

parent cf3e3406
......@@ -636,16 +636,22 @@ mkHoleError ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort })
tyvars_msg = map loc_msg tyvars
msg = vcat [ hang (ptext (sLit "Found hole") <+> quotes (ppr occ))
2 (ptext (sLit "with type:") <+> pprType (ctEvPred (ctEvidence ct)))
, ppUnless (null tyvars_msg) (ptext (sLit "Where:") <+> vcat tyvars_msg)
, pts_hint ]
, ppUnless (null tyvars) (ptext (sLit "Where:") <+> vcat tyvars_msg)
, hint ]
; (ctxt, binds_doc, _) <- relevantBindings False ctxt ct
-- The 'False' means "don't filter the bindings"; see Trac #8191
; mkErrorMsgFromCt ctxt ct (msg $$ binds_doc) }
where
pts_hint
hint
| TypeHole <- hole_sort
, HoleError <- cec_type_holes ctxt
= ptext (sLit "To use the inferred type, enable PartialTypeSignatures")
| ExprHole <- hole_sort -- Give hint for, say, f x = _x
, lengthFS (occNameFS occ) > 1 -- Don't give this hint for plain "_", which isn't legal Haskell
= ptext (sLit "Or perhaps") <+> quotes (ppr occ)
<+> ptext (sLit "is mis-spelled, or not in scope")
| otherwise
= empty
......
......@@ -8594,19 +8594,6 @@ defined on top-level or inside complex expressions. Holes allow the user to
check the type of the term they are about to write.
</para>
<para>
To run and test a piece of code containing holes, use the
<literal>-fdefer-typed-holes</literal> flag. This flag defers errors
produced by typed holes and converts them into warnings. The result is that
typed hole errors are converted into warnings (controlled by
<literal>-fwarn-typed-holes</literal>). The result is that a hole will behave
like <literal>undefined</literal>, but with the added benefits that it shows a
warning at compile time and will show another warning message if it gets
evaluated. This behaviour follows that of the
<literal>-fdefer-type-errors</literal> option, which implies
<literal>-fdefer-typed-holes</literal>. See <xref linkend="defer-type-errors"/>.
</para>
<para>
For example, compiling the following module with GHC:
<programlisting>
......@@ -8628,29 +8615,31 @@ hole.hs:2:7:
</para>
<para>
Multiple typed holes can be used to find common type variables between expressions. For example:
<programlisting>
sum :: [Int] -> Int
sum xs = foldr _f _z xs
</programlisting>
Shows:
<programlisting>
holes.hs:2:15:
Found hole `_f' with type: Int -> Int -> Int
In the first argument of `foldr', namely `_'
In the expression: foldr _a _b _c
In an equation for `sum': sum x = foldr _a _b _c
holes.hs:2:17:
Found hole `_z' with type: Int
In the second argument of `foldr', namely `_'
In the expression: foldr _a _b _c
In an equation for `sum': sum x = foldr _a _b _c
</programlisting>
Here are some more details:
<itemizedlist>
<listitem>
<para>
A "<literal>Found hole</literal>" error usually terminates compilation, like
any other type error. After all, you have omitted some code from your program.
Nevertheless, you can run and test a piece of code containing holes, by using the flag
<option>-fdefer-typed-holes</option> flag. This flag defers errors
produced by typed holes until runtime, and converts them into compile-time warnings.
These warnings can in turn
be suppressed entirely by <option>-fnowarn-typed-holes</option>).
</para>
<para>
Unbound identifiers with the same name are never unified, even within the same function, but always printed individually.
The result is that a hole will behave
like <literal>undefined</literal>, but with the added benefits that it shows a
warning at compile time and will show another warning message if it gets
evaluated at runtime.. This behaviour follows that of the
<literal>-fdefer-type-errors</literal> option, which implies
<literal>-fdefer-typed-holes</literal>. See <xref linkend="defer-type-errors"/>.
</para>
</listitem>
<listitem><para>
Unbound identifiers with the same name are never unified, even within the
same function, but shown individually.
For example:
<programlisting>
cons = _x : _x
......@@ -8676,8 +8665,20 @@ unbound.hs:1:13:
In the expression: _x : _x
In an equation for `cons': cons = _x : _x
</programlisting>
This ensures that an unbound identifier is never reported with a too polymorphic type, like
<literal>forall a. a</literal>, when used multiple times for types that can not be unified.
Notice the two different types reported for the two different occurrences of <literal>_x</literal>.
</para></listitem>
<listitem><para>
No language extension is required to use typed holes. The lexeme "<literal>_</literal>" was previously
illegal in Haskell, but now has a more informative error message. The lexeme "<literal>_x</literal>"
is a perfectly legal varaible, and its behaviour is unchanged when it is in scope. For example
<programlisting>
f _x = _x + 1
</programlisting>
does not elict any errors. Only a variable starting with an underscore <emphasis>that is not in scope</emphasis>
is treated as an error (which it always was), albeit now with a more informative error message
</para></listitem>
</itemizedlist>
</para>
</sect1>
......
T9497a.hs:2:8: Warning:
Found hole ‘_main’ with type: IO ()
Or perhaps ‘_main’ is mis-spelled, or not in scope
Relevant bindings include main :: IO () (bound at T9497a.hs:2:1)
In the expression: _main
In an equation for ‘main’: main = _main
......@@ -9,6 +9,7 @@ holes3.hs:3:5:
holes3.hs:6:7:
Found hole ‘_gr’ with type: Char
Or perhaps ‘_gr’ is mis-spelled, or not in scope
Relevant bindings include
x :: Int (bound at holes3.hs:6:3)
g :: Int -> Char (bound at holes3.hs:6:1)
......@@ -17,6 +18,7 @@ holes3.hs:6:7:
holes3.hs:8:5:
Found hole ‘_aa’ with type: [Char]
Or perhaps ‘_aa’ is mis-spelled, or not in scope
Relevant bindings include h :: [Char] (bound at holes3.hs:8:1)
In the first argument of ‘(++)’, namely ‘_aa’
In the expression: _aa ++ "a"
......@@ -25,6 +27,7 @@ holes3.hs:8:5:
holes3.hs:11:15:
Found hole ‘_x’ with type: b0
Where: ‘b0’ is an ambiguous type variable
Or perhaps ‘_x’ is mis-spelled, or not in scope
Relevant bindings include
y :: [a] (bound at holes3.hs:11:3)
z :: [a] -> [a] (bound at holes3.hs:11:1)
......
T9497d.hs:2:8:
Found hole ‘_main’ with type: IO ()
Or perhaps ‘_main’ is mis-spelled, or not in scope
Relevant bindings include main :: IO () (bound at T9497d.hs:2:1)
In the expression: _main
In an equation for ‘main’: main = _main
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment