Type constructor has conflicting definitions in the module and its hs-boot/hsig file [GHC-15843]

The type constructor definitions in modules must agree with the cycle-breaking hs-boot modules as well as with the Backpack hsig module interface files, if any of the two exist.

Type constructor definitions in hs-boot modules and hsig files are typically given by forward data declarations (data declarations without any data constructors, only the type constructor is declared), as that is the whole purpose of those two “interface-like modules”.

Therefore, this error message likely comes up in one of two situations:

  1. The kinds of type constructors differ in the interface module and in the actual module.
  2. The type constructor kinds match, but the roles of some of the type arguments don’t match.

The first situation can be typically be easily fixed by making sure the type declaration in the boot/sig module has the same number of type arguments as the declaration in the module and making sure any kind declarations are equal. The second situation can normally be solved by given a type role declaration to the type constructor. See the two examples below.

Examples

The types have different kinds

The types have different kinds. If you are using kind declarations or annotations, make sure these match. Alternatively, you may have given different numbers of type arguments to the same type constructor – make sure the number of arguments match.

Example error text

X.hs:3:1: error: [GHC-15843]
    • Type constructor ‘X’ has conflicting definitions in the module
      and its hs-boot file.
      Main module: type X :: * -> *
                   data X a = X a
        Boot file: type X :: *
                   data X
      The types have different kinds.
    • In the data type declaration for ‘X’
  |
3 | data X a = X a
  | ^^^^^^^^^^^^^^
DifferentKinds.hs
Before
module DifferentKinds where

data ATypeConstructor a b c = ATC a b c

-- The .hs-boot or .hsig module
module DifferentKinds where

data ATypeConstructor a b
After
module DifferentKinds where

data ATypeConstructor a b c = ATC a b c

-- The .hs-boot or .hsig module
module DifferentKinds where

data ATypeConstructor a b c
The roles do not match

The roles of the type constructor arguments do not match. A typical reason for the roles not to match is that, in .hs-boot and .hsig modules, the role of arguments in the forward type declarations defaults to representional.

In the following example, the role of the type argument in the actual module is phantom, because it doesn’t occur in the RHS of the data declaration. Since representational is inferred for the hs-boot declaration.

Example error text

T9204.hs:7:1: error: [GHC-15843]
    • Type constructor ‘D’ has conflicting definitions in the module
      and its hs-boot file.
      Main module: type role D phantom
                   type D :: * -> *
                   data D a
        Boot file: type D :: * -> *
                   data D a
      The roles do not match.
      NB: roles on abstract types default to ‘representational’ in hs-boot files.
    • In the data type declaration for ‘D’
DifferentRoles.hs
Before
module DifferentRoles where

data D a

-- .hs-boot or .hsig boot
module DifferentRoles where

data D a

After
module DifferentRoles where

data D a

-- .hs-boot or .hsig boot
{-# LANGUAGE RoleAnnotations #-}
module DifferentRoles where

type role D phantom
data D a