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