Note [FunTyFlag]
FunTyFlag is used principally in the FunTy constructor of Type.
FunTy FTF_T_T t1 t2 means t1 -> t2
FunTy FTF_C_T t1 t2 means t1 => t2
FunTy FTF_T_C t1 t2 means t1 -=> t2
FunTy FTF_C_C t1 t2 means t1 ==> t2
However, the FunTyFlag in a FunTy is just redundant, cached
information. In (FunTy { ft_af = af, ft_arg = t1, ft_res = t2 })
(isPredTy t1) (isPredTy ty) FunTyFlag
False False FTF_T_T
False True FTF_T_C
True False FTF_C_T
True True FTF_C_C
where isPredTy is defined in GHC.Core.Predicate, and sees if t1's
kind is Constraint. See GHC.Core.Type.chooseFunTyFlag, and
GHC.Core.Predicate Note [Types for coercions, predicates, and evidence]
The term (Lam b e) doesn't carry an FunTyFlag; instead it uses
mkFunctionType when we want to get its types; see mkLamType. This is
just an engineering choice; we could cache here too if we wanted.
Why bother with all this? After all, we are in Core, where (=>) and
(->) behave the same. We maintain this distinction throughout Core so
that we can cheaply and conveniently determine
* How to print a type
* How to split up a type: tcSplitSigmaTy
* How to specialise it (over type classes; GHC.Core.Opt.Specialise)
For the specialisation point, consider
(\ (d :: Ord a). blah). We want to give it type
(Ord a => blah_ty)
with a fat arrow; that is, using mkInvisFunTy, not mkVisFunTy.
Why? Because the /specialiser/ treats dictionary arguments specially.
Suppose we do w/w on 'foo', thus (#11272, #6056)
foo :: Ord a => Int -> blah
foo a d x = case x of I# x' -> $wfoo @a d x'
$wfoo :: Ord a => Int# -> blah
Now, at a call we see (foo @Int dOrdInt). The specialiser will
specialise this to $sfoo, where
$sfoo :: Int -> blah
$sfoo x = case x of I# x' -> $wfoo @Int dOrdInt x'
Now we /must/ also specialise $wfoo! But it wasn't user-written,
and has a type built with mkLamTypes.
Conclusion: the easiest thing is to make mkLamType build
(c => ty)
when the argument is a predicate type. See GHC.Core.TyCo.Rep
Note [Types for coercions, predicates, and evidence] References 1
- Types for coercions, predicates, and evidence GHC.Core.Predicate
Referenced by 7
- Function type constructors and FunTy GHC.Builtin.Types.Prim ×2
- GHC.Core.Type call site ×2
- GHC.Core.TyCo.Rep call site
- Function types GHC.Core.TyCo.Rep
- GHC.Types.Var call site