The `-Wno-explicit-forall` warning and the `{-# AMBIGUOUS #-}` pragma
Motivation
In modern GHC Haskell there are a lot of libraries that do a lot of type-level programming but still want to offer a nice interface to the user, however, this interface is hard to provide if the compiler doesn't help; I want to motivate an propose two changes in the direction of being able to help the programmer with offering nicer interfaces.
-Wno-explicit-forall
Proposal 1 - For many functions with APIs that have many type variables to specify, it is very important to offer them in an order that the type variables are needed to fill in, this is not necessarily the case with implicit forall
s. It is also possible that the programmer specifies the type variables in a specific order that is known to the user but they forget the type signature, it would be nice to be able to remind them in the case they forgot.
In particular this means that
f :: a -> f a
will throw a warning like "warning [-Wno-explicit-forall] 'f' doesn't use explicit quantification"
,
whereas f :: forall f a. a -> f a
won't.
{-# AMBIGUOUS #-}
pragma
Proposal 2 - the In many cases we want to explicitly pass a Proxy
to our functions if we have to specify type arguments like in f :: C a => Int
, however there might be valid reasons to not do so when trying to offer a nice API; e.g. it might be nicer to offer a function like
forall foo bar baz. Bar bar -> Baz baz
instead of forall {proxy} foo bar baz. proxy foo -> ...
in some cases, however I don't think that this is a reason for enable -XAllowAmbiguousTypes
which defers the ambiguity check for the entire module and an error that might be valid in many cases within the module does not occur because of one conscious decision against it.
Hence I would like to propose an {-# AMBIGUOUS foo #-}
pragma which defers the ambiguity to the usage site for exactly one definition.
There are three more advantages to that approach
- it aligns with the usual replacement of whole module extensions vs per definition extensions like in the case of
{-# OVERLAPP* #-}
- it allows to forbid specifying
{-# AMBIGUOUS #-}
functions without explicitforall
s, which would make the whole type applications interface much nicer - this could be documented in the API of the type; i.e. we could explicitly state that a definition was made with type applications in mind
This issue is mainly to collect opinions on this; would it be possible, have there already been similar or identical proposals, what would be possible caveats, do I need a GHC proposal for this?