Open nomeata opened 8 years ago
I'm strongly in favour of this proposal. From a teaching perspective, it's annoying to not be able to write the signatures of instances.
My only niggle is the inconsistent naming of the language extension itself: we have KindSignatures
and PatternSignatures
, so I think these ought to be called InstanceSignatures
.
Strongly in favor of this proposal as well, but can we change it to InstanceSignatures
, please, echoing @zenzike ? Although it would be on by default, and so the only users who type the name would be saying -XNoInstanceSignatures
..... and there seems to be absolutely no downsides to enabling this by default (other than lack of Haskell98/2010 conformity). So perhaps it's not worth the bother if the whole thing is going to be deprecated anyway.
So perhaps it's not worth the bother if the whole thing is going to be deprecated anyway.
We still need a proposal to allow this in the new report, even if it is not a language extension, right?
Yes. The "not worth the bother" part was about renaming InstanceSigs
to InstanceSignatures
.
I'm +1 on this extension, because I also think it's an oddly strange restriction, when we can give signatures in so many other scopes. But I am going to highlight this bit for a moment:
If people really feel the need to that there needs to be something to be discussed for the sake of having an discussion, one might discuss the choice of GHC to allow more general types that required by the instance.
This seems to be just fine to me, if I'm understanding you correctly. After all, you can give a more general type than "required" to lot of different functions, so this seems consistent!
Assuming the rest of us agree, then, it'd be best to just move this sentence out of "Unresolved questions" bracket. And also-- it's worded a little oddly since it directly references the proposal process itself; it's sort of "breaking the fourth wall" which makes the "flow" of reading break a bit.
But also... please! Provide a code example, especially if this will be the case. Yes, this extension is trivial from our POV, but anyone who comes and reads it needs to be able to clearly, unambiguously understand it. It's easiest to do this with a small piece of code (and, you can also take the opportunity to demo more general instance signatures, as mentioned).
I did now include the GHC doc as the detailed description.
Note that InstanceSigs
+ ScopedTypeVariables
is a bit unintuitive, because the type variables in the class are already scoped over the entire definition. For example,
class Foo a where
bar :: Ord b => b -> a
instance What a => Foo a where
bar :: forall b. Ord b => b -> a -- not "forall a b."
bar = ...
where
helper1 :: b -- needs ScopedTypeVariables
helper1 = ...
helper2 :: a -- doesn't need ScopedTypeVariables
helper2 = ...
Just a point I thought I'd mention here.
Good point. I hope that ScopedTypeVariables
will also be a default in a future standard :-)
Is there anything reasonable we can do to improve this corner case?
This all seems hunky-dory to me. The instance declaration brings a
into scope, and so I shouldn't expect to bring it into scope again in the instance sig.
However, I'm not sure I agree with your "doesn't need ScopedTypeVariables" comment, as I thought type variables in instance heads were brought into scope only with that extension. (This is in contrast to type variables in class heads, which are always brought into scope.)
@goldfirere I guess I meant it's a little bit inconsistent, as in, one might expect they'd have to write
instance forall a. What a => Foo a where
to get a
to scope over the body and any locally defined helper functions, a la scoped type variables.
@goldfirere Regarding your second point about not needing ScopedTypeVariables
, it's true! (Unless I'm missing something).
This compiles fine:
class What a where
what :: a
instance What (Maybe a) where
what = x
where
x :: Maybe a
x = Nothing
I think if this were true,
type variables in instance heads were brought into scope only with that extension
you'd get a "couldn't match type a with a1" error.
Err, except that by my logic, this should be a type error, but it isn't:
class What a where
what :: a
instance What (Maybe a) where
what :: Maybe a
what = undefined :: b
Ok, @goldfirere is correct that you need ScopedTypeVariables
if you want to refer to type variables in the instance head or in polymorphic typeclass functions, so there's actually no strange interaction with InstanceSigs
at all!
I agree with @mitchellwrosen that it is odd that instance Foo a where ...
brings a
into scope without an explicit forall. But that's orthogonal to this proposal. Thanks, @mitchellwrosen , for working all that out!
I fully support this proposal. I find this extension very useful for code comprehension and documentation. I often write the instance method signature to help me think about the implementation of the method.
Rendered version: https://github.com/nomeata/rfcs/blob/instancesigs/0000-instancesigs.rst