By: Tom Sydney Kerckhove <syd@cs-syd.eu>
#1637, add a typeApplications option for restricted functions
Reviving #1667 (closed stale). A function restriction may now set
'typeApplications' to require or forbid visible type applications at use sites,
so a silent change to an inferred type cannot change behaviour unnoticed.
- functions:
- {name: show, typeApplications: required} # >= 1 type argument
- {name: fromIntegral, typeApplications: 2} # >= N type arguments
- {name: id, typeApplications: forbidden} # none
'required' demands at least one type argument, an integer N demands at least N
(so fromIntegral, which needs both type variables fixed, can require two), and
'forbidden' demands none. It also applies to data constructors in patterns.
Only positions that can carry a visible type application are checked: the head
of an expression and a constructor in a prefix pattern. A name in a type
signature, a class method signature, a record field declaration or a binder is
never flagged, and neither is an operator used infix or in a section, or a
constructor pattern in record or infix form, since the advice cannot be
followed there. Parenthesised, as in (<+>), the operator is back in prefix
position and is still checked.
A '@_' argument does not count towards 'required', since it leaves the type
just as inferred as writing no type argument at all, so 'fromIntegral @_ @_' is
flagged under 'typeApplications: 2'. It does count towards 'forbidden', which
asks that no visible type application is written at all.
When several rules restrict one name's type applications, the last-declared one
wins. Merging them would be arbitrary: a name cannot sensibly both require and
forbid a type application.