This is valid syntax in GHC 9. What do the {..} mean (as distinct from (..) which GHC 8.10 requires here)?
ign :: forall {f :: Type -> Type} {p}. Applicative f => p -> f ()
ign _ = pure ()
This is valid syntax in GHC 9. What do the {..} mean (as distinct from (..) which GHC 8.10 requires here)?
ign :: forall {f :: Type -> Type} {p}. Applicative f => p -> f ()
ign _ = pure ()
See 6.4.14.1. Inferred vs. specified type variables:
..is a specified type{..}is an inferred typeforall a.andforall {a}.are invisible quantifiers that GHC will instantiate automatically by unification.This means
const True EQinstantiates a (@Bool) and b (@Ordering) without the users help.If the user wants to explicitly instantiate them they can "override their visibility", using visible type applications. That's why they are specified types. (although "specifiable" might be a more accurate terminology)
If for some reason we only want to specify b (without summoning the "snail squad":
@_, umm "partial type signatures") we can make a an inferred type. Then the first type is droppedFor your example it means ghc must infer the type of f and p. You cannot write
ign @IO @Int.This becomes more useful when you have kind polymorphism. If you define
you must specify the kind k when instantiating
MkApply @Type @[] @Intbut this kind is implied by both[]andInt. You might prefer marking k as inferred inMkApplyso you can writeMkApply @[] @Int