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