Implict parameters and monomorphism
Robert Ennals
Robert.Ennals@cl.cam.ac.uk
Wed, 25 Apr 2001 09:52:25 +0100
> On Tue, Apr 24, 2001 at 04:04:54PM -0700, Simon Peyton-Jones wrote:
> > Question 1: can we "inherit" implicit parameters
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > Consider this:
> >
> > f x = (x::Int) + ?y
> > ...
> > f :: Int -> Int
> > [versus]
> > f :: (?y::Int) => Int -> Int
> >
> > Question 2: type signatures
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > OK, so it it legal to give an explicit, user type signature to f, thus:
> >
> > f :: Int -> Int
> > f x = (x::Int) + ?y
> > ...
>
> It seems desirable to provide some way to allow either possible answer
> to Question 1 (i.e., dynamically scoped or statically scoped ?y). Is
> there some syntax for that (other than providing a type signature,
> which I agree is not desirable)?
One alternative (which I played around with a while ago) is to have implicit
parameters explicitly bound at a function definition.
Thus if we want to "inherit" our implicit paramater, we would have:
f ?y x = (x :: Int) + ?y
with type
f :: (?y :: Int) => Int -> Int
If the "?y" isn't put on the function binding, then it needs to have occurred
in an enclosing function binding. Eg
g ?y = let f x = ... in ...
The same approach extends to definitions of non-functions, now taking on
function-like syntax, to take implicit parameters.
For the "z" example, we get
z ?y = (x::Int) + ?y
This still gives us a type of
z :: (?y :: Int) => Int
but the "function-like" nature is now explicit, and thus IMHO, in this case
there is a more reasonable argument for dropping the monomorphism restriction.
If I write
let z ?y = x + ?y in z + z
In seems far more obvious that z will be evaluated twice.
Hmmm. I haven't made this particularly clear, but hopefully most of you can
see what I am getting at.
Semantics is entirely as with existing implicit parameter proposals. This is
all just syntax.
-Rob