2.2. Version 9.2.1

2.2.1. Language

  • ImpredicativeTypes: Finally, polymorphic types have become first class! GHC 9.2 includes a full implementation of the Quick Look approach to type inference for impredicative types, as described in in the paper A quick look at impredicativity (Serrano et al, ICFP 2020). More information here: Impredicative polymorphism. This replaces the old (undefined, flaky) behaviour of the ImpredicativeTypes extension.

  • Kind inference for data/newtype instance declarations is slightly more restrictive than before. See the user manual Kind inference for data/newtype instance declarations. This is a breaking change, albeit a fairly obscure one that corrects a specification bug.

  • GHC is stricter about checking for out-of-scope type variables on the right-hand sides of associated type family instances that are not bound on the left-hand side. As a result, some programs that were accidentally accepted in previous versions of GHC will now be rejected, such as this example:

    class Funct f where
      type Codomain f
    instance Funct ('KProxy :: KProxy o) where
      type Codomain 'KProxy = NatTr (Proxy :: o -> Type)
    

    Where:

    data Proxy (a :: k) = Proxy
    data KProxy (t :: Type) = KProxy
    data NatTr (c :: o -> Type)
    

    GHC will now reject the o on the right-hand side of the Codomain instance as being out of scope, as it does not meet the requirements for being explicitly bound (as it is not mentioned on the left-hand side) nor implicitly bound (as it is not mentioned in an outermost kind signature, as required by Scoping of class parameters). This program can be repaired in a backwards-compatible way by mentioning o on the left-hand side:

    instance Funct ('KProxy :: KProxy o) where
      type Codomain ('KProxy @o) = NatTr (Proxy :: o -> Type)
      -- Alternatively,
      -- type Codomain ('KProxy :: KProxy o) = NatTr (Proxy :: o -> Type)
    

2.2.2. Compiler

2.2.3. Runtime system

  • The heap profiler now has proper treatment of pinned ByteArray#s. Such heap objects will now be correctly attributed to their appropriate cost centre instead of merely being lumped into the PINNED category. Moreover, we now correctly account for the size of the array, meaning that space lost to fragmentation is no longer counted as live data.

2.2.4. ghc-prim library

  • Void# is now a type synonym for the unboxed tuple (# #). Code using Void# now has to enable UnboxedTuples.

2.2.5. ghc library

  • There is a significant refactoring in the solver; any type-checker plugins will have to be updated, as GHC no longer uses flattening skolems or flattening metavariables.

  • Type checker plugins which work with the natural numbers now should use naturalTy kind instead of typeNatKind, which has been removed.

  • The con_args field of ConDeclGADT has been renamed to con_g_args. This is because the type of con_g_args is now different from the type of the con_args field in ConDeclH98:

    data ConDecl pass
      = ConDeclGADT
          { ...
          , con_g_args :: HsConDeclGADTDetails pass -- ^ Arguments; never infix
          , ...
          }
    
      | ConDeclH98
          { ...
          , con_args :: HsConDeclH98Details pass -- ^ Arguments; can be infix
          , ...
          }
    

    Where:

    -- Introduced in GHC 9.2; was called `HsConDeclDetails` in previous versions of GHC
    type HsConDeclH98Details pass
       = HsConDetails (HsScaled pass (LBangType pass)) (XRec pass [LConDeclField pass])
    
    -- Introduced in GHC 9.2
    data HsConDeclGADTDetails pass
       = PrefixConGADT [HsScaled pass (LBangType pass)]
       | RecConGADT (XRec pass [LConDeclField pass])
    

    Unlike Haskell98-style constructors, GADT constructors cannot be declared using infix syntax, which is why HsConDeclGADTDetails lacks an InfixConGADT constructor.

    As a result of all this, the con_args field is now partial, so using con_args as a top-level field selector is discouraged.

2.2.6. base library

  • It’s possible now to promote the Natural type:

    data Coordinate = Mk2D Natural Natural
    type MyCoordinate = Mk2D 1 10
    

    The separate kind Nat is removed and now it is just a type synonym for Natural. As a consequence, one must enable TypeSynonymInstances in order to define instances for Nat.

    The Numeric module recieves showBin and readBin to show and read integer numbers in binary.