
What Dominique said is right, and it is also the way it is actually implemented. On 2015-02-05 22:30, Simon Peyton Jones wrote:
Oh gosh you are absolutely right. Ordinary, lexically scoped type variables only scope over the RHS of the relevant binding, not the body of the let. I was completely wrong about that.
In which case my objection is much milder: - the inconsistency of treatment wrt ordinary type variables (which require a forall; and yes, you can't give a forall for wildcards)
True. It is understandable that is surprising that enabling an extension that doesn't have wildcards (or anything similar) in its name affects the behaviour of wildcards.
- the lack of documentation
I will take care of this. It is already on the wiki page, but it is indeed missing from the user manual.
The system would be simpler without this. So, is it really important? If so, we could add it later.
I'm not so sure it would make things much simpler. Wildcards still need to be stored in the TcSigInfo because we need to emit insoluble hole constraints for them. We wouldn't need to bring them in scope or check whether they're already in scope in a couple of places, but to me, that doesn't seem like a good reason. If we were to remove this behaviour, and add it back later, I suppose something would have to be changed by then, but what? A forall-construct for wildcards? I do believe this behaviour is useful, we would lose expressiveness if we were to remove it. Note that we don't have the same problem with backwards compatibility that ScopedTypeVariables had, that requires the user to explicitly indicate with a forall which type variables to lexically scope to avoid breaking existing programs. We might as well make named wildcards lexically scoped by default, not even opt-out (as was the case in my initial proposal). About using a Maybe for sig_id to fix 10045: I tried it out, and your solution does indeed fix it. In order for TcSigInfo to still implement NamedThing, I used an 'Either Name TcId' instead of a 'Maybe TcId'. Do you prefer a separate data type for this instead of an Either? (Please come up with a good name for it in that case :) Unfortunately, some of my tests started failing, so I'll post something on Phabricator as soon as I have worked out the kinks. Cheers, Thomas
Sorry to make such a misleading post.
Simon
| -----Original Message----- | From: dominique.devriese@gmail.com [mailto:dominique.devriese@gmail.com] | On Behalf Of Dominique Devriese | Sent: 05 February 2015 20:13 | To: Simon Peyton Jones | Cc: Thomas Winant; ghc-devs@haskell.org; Frank Piessens | Subject: Re: Partial type sigs | | Simon, | | 2015-02-05 17:44 GMT+01:00 Simon Peyton Jones
: | > 3. It interferes with generalisation. | > | > For (3), consider | > | > let f :: _a -> _a | > | > f xs = reverse xs | > | > in (f True, f ‘x’) | > | > Here, f gets the type f :: forall b. [b] -> [b], and _a is unifed with | [b]. | > | > So it simply doesn’t make sense for _a to appear in the body. What | would it | > mean to say | > | > let f :: _a -> _a | > | > f xs = reverse xs | > | > in (f (True :: _a), f ‘x’) | | Isn't this a different case than Thomas' example? As I understand it, | an equivalent of his example would have the wildcard in scope in the | body of f, not in the body of the let. Something like this: | | let f :: _a -> _a | f xs = reverse (xs :: _a) | in (f [True], f "x") | | or | | let f :: _a -> _a | f xs = let ys :: _a | ys = tail xs | in reverse ys | in (f [True], f "x") | | I agree with what you say about _a being in scope in the body of the | if, but I don't see a problem with _a being in scope in the body of f. | Do you? | | Note also that I haven't yet checked which of both is actually | implemented. | | Regards, | Dominique
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm