Note [Function type constructors and FunTy]

GHC/Builtin/Types/Prim.hs:566 compiler

We have four distinct function type constructors, and a type synonym

 FUN :: forall (m :: Multiplicity) ->
        forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
        TYPE rep1 -> TYPE rep2 -> Type

 (=>)  :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
          CONSTRAINT rep1 -> TYPE rep2 -> Type

 (==>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
          CONSTRAINT rep1 -> CONSTRAINT rep2 -> Constraint

 (-=>) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}.
          TYPE rep1 -> CONSTRAINT rep2 -> Constraint

 type (->) = FUN Many

For efficiency, all four are always represented by
  FunTy { ft_af :: FunTyFlag, ft_mult :: Mult
        , ft_arg :: Type, ft_res :: Type }
rather than by using a TyConApp.

* The four TyCons FUN, (=>), (==>), (-=>) are all wired in.
  But (->) is just a regular synonym, with no special treatment;
  in particular it is not wired-in.

* The ft_af :: FunTyFlag distinguishes the four cases.
  See Note [FunTyFlag] in GHC.Types.Var.

* The ft_af field is redundant: it can always be gleaned from
  the kinds of ft_arg and ft_res.  See Note [FunTyFlag] in GHC.Types.Var.

* The ft_mult :: Mult field gives the first argument for FUN
  For the other three cases ft_mult is redundant; it is always Many.
  Note that of the four type constructors, only `FUN` takes a Multiplicity.

* Functions in GHC.Core.Type help to build and decompose `FunTy`.
  * funTyConAppTy_maybe
  * funTyFlagTyCon
  * tyConAppFun_maybe
  * splitFunTy_maybe
  Use them!

References 1

Referenced by 4