summaryrefslogtreecommitdiff
path: root/docs/users_guide/exts/defer_type_errors.rst
blob: 818287bfdc32c9c35153facb38a9be218c316752 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
.. _defer-type-errors:

Deferring type errors to runtime
================================

While developing, sometimes it is desirable to allow compilation to
succeed even if there are type errors in the code. Consider the
following case: ::

    module Main where

    a :: Int
    a = 'a'

    main = print "b"

Even though ``a`` is ill-typed, it is not used in the end, so if all
that we're interested in is ``main`` it can be useful to be able to
ignore the problems in ``a``.

For more motivation and details please refer to the
:ghc-wiki:`Wiki <defer-errors-to-runtime>` page or the `original
paper <http://dreixel.net/research/pdf/epdtecp.pdf>`__.

Enabling deferring of type errors
---------------------------------

The flag :ghc-flag:`-fdefer-type-errors` controls whether type errors are
deferred to runtime. Type errors will still be emitted as warnings, but
will not prevent compilation. You can use :ghc-flag:`-Wno-deferred-type-errors`
to suppress these warnings.

This flag implies the :ghc-flag:`-fdefer-typed-holes` and
:ghc-flag:`-fdefer-out-of-scope-variables` flags, which enables this behaviour
for `typed holes <#typed-holes>`__ and variables. Should you so wish, it is
possible to enable :ghc-flag:`-fdefer-type-errors` without enabling
:ghc-flag:`-fdefer-typed-holes` or :ghc-flag:`-fdefer-out-of-scope-variables`,
by explicitly specifying :ghc-flag:`-fno-defer-typed-holes
<-fdefer-typed-holes>` or :ghc-flag:`-fno-defer-out-of-scope-variables
<-fdefer-out-of-scope-variables>` on the command-line after the
:ghc-flag:`-fdefer-type-errors` flag.

At runtime, whenever a term containing a type error would need to be
evaluated, the error is converted into a runtime exception of type
``TypeError``. Note that type errors are deferred as much as possible
during runtime, but invalid coercions are never performed, even when
they would ultimately result in a value of the correct type. For
example, given the following code: ::

    x :: Int
    x = 0

    y :: Char
    y = x

    z :: Int
    z = y

evaluating ``z`` will result in a runtime ``TypeError``.

Deferred type errors in GHCi
----------------------------

The flag :ghc-flag:`-fdefer-type-errors` works in GHCi as well, with one
exception: for "naked" expressions typed at the prompt, type errors
don't get delayed, so for example: ::

    Prelude> fst (True, 1 == 'a')

    <interactive>:2:12:
        No instance for (Num Char) arising from the literal `1'
        Possible fix: add an instance declaration for (Num Char)
        In the first argument of `(==)', namely `1'
        In the expression: 1 == 'a'
        In the first argument of `fst', namely `(True, 1 == 'a')'

Otherwise, in the common case of a simple type error such as typing
``reverse True`` at the prompt, you would get a warning and then an
immediately-following type error when the expression is evaluated.

This exception doesn't apply to statements, as the following example
demonstrates:

.. code-block:: none

    Prelude> let x = (True, 1 == 'a')

    <interactive>:3:16: Warning:
        No instance for (Num Char) arising from the literal `1'
        Possible fix: add an instance declaration for (Num Char)
        In the first argument of `(==)', namely `1'
        In the expression: 1 == 'a'
        In the expression: (True, 1 == 'a')
    Prelude> fst x
    True

Limitations of deferred type errors
-----------------------------------
The errors that can be deferred are:

- Out of scope term variables
- Equality constraints; e.g. ``ord True`` gives rise to an insoluble equality constraint ``Char ~ Bool``, which can be deferred.
- Type-class and implicit-parameter constraints

All other type errors are reported immediately, and cannot be deferred; for
example, an ill-kinded type signature, an instance declaration that is
non-terminating or ill-formed, a type-family instance that does not
obey the declared injectivity constraints, etc etc.

In a few cases, equality constraints cannot be deferred.  Specifically:

- Kind errors in a type or kind signature, partial type signatures, or pattern signature.
  e.g. ::

    f :: Int Bool -> Char

  This type signature contains a kind error which cannot be deferred.

- Type equalities under a forall (c.f. `#14605
  <https://gitlab.haskell.org/ghc/ghc/issues/14605>`_).

- Kind errors in a visible type application. e.g. ::

    reverse @Maybe xs

- Kind errors in a ``default`` declaration.  e.g. ::

    default( Double, Int Int )

- Errors involving linear types (c.f. :ghc-ticket:`20083`). e.g. ::

    f :: a %1 -> a
    f _  = ()