# 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

```