Pattern matching on GADTs without MonoLocalBinds is fragile [GHC-58008]

Flag: -Wgadt-mono-local-binds
Enabled by default

This warning is triggered on pattern matching involving GADTs, if MonoLocalBinds is disabled. Type inference can be fragile in this case. See the OutsideIn(X) paper and Let-generalisation for more details. To resolve this warning, you can enable MonoLocalBinds or an extension implying it (GADTs or TypeFamilies). The warning is also triggered when matching on GADT-like pattern synonyms (i.e. pattern synonyms containing equalities in provided constraints). In previous versions of GHC (9.2 and below), it was an error to pattern match on a GADT if neither GADTs nor TypeFamilies were enabled.

Examples

Pattern matching on GADTs without MonoLocalBinds

Message

GADTWithoutMonoBind.hs:7:3: warning: [GHC-58008] [-Wgadt-mono-local-binds]
    Pattern matching on GADTs without MonoLocalBinds is fragile.
    Suggested fix:
      Enable any of the following extensions: GADTs, TypeFamilies
  |
7 | f A = ()
  |   ^

Explanation

When using GADTs, the type system is different in the sense that it’s not possible to derive the principal type of the function f. Both f :: A a -> () and f :: A () -> () can be considered the most general typing for the function. The MonoLocalBinds extension uses a slightly more conservative policy in order to be able to derive the type properly in such cases.

GADTWithoutMonoBind.hs
Before
module GADTWithoutMonoBind where

data A a where
  A :: A ()

f :: A () -> ()
f A = ()
After
{-# LANGUAGE MonoLocalBinds #-}

module GADTWithoutMonoBind where

data A a where
  A :: A ()

f :: A () -> ()
f A = ()