Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use constructor when alias of type is in scope #548

Closed
Laegluin opened this issue Jun 18, 2018 · 5 comments
Closed

Cannot use constructor when alias of type is in scope #548

Laegluin opened this issue Jun 18, 2018 · 5 comments

Comments

@Laegluin
Copy link
Contributor

Laegluin commented Jun 18, 2018

When defining a type alias for a generic type, like Option, that instantiates a type parameter, it is impossible to use the constructor for anything but the type of the alias:

// works
let something: Option String = Some "something"

type OptionalInt = Option Int

// this is now broken because only `Int` is allowed as type for `Some`
let something: Option String = Some "something"

I'm not entirely sure if this is a bug, but it's certainly unexpected, and the error messages are quite confusing,
since you first get an error for the constructor and then for the binding, which seemingly contradict each other.

@Marwes
Copy link
Member

Marwes commented Jun 19, 2018

I believe this is caused by another fix I made in 0.8 to make aliases like this import the constructors of the type they aliases as well (so this brings Some : Int -> Option Int into scope, whereas before it didn't do anything).

Only way to fix this might be to make variants scoped under the type (Option.Some, Option.None). Open for suggestions though.

@Laegluin
Copy link
Contributor Author

Laegluin commented Jun 20, 2018

Only way to fix this might be to make variants scoped under the type (Option.Some, Option.None). Open for suggestions though.

Would it be possible to look up the original type that is aliased and import its variants without any type parameters applied? That would import more than you may need, but it wouldn't shadow a more general constructor.

Optionally scoping variants under the type seems useful on its own though, to prevent collisions with identical variants of different types. I'd expect variants qualified like that to work like they do now, so OptionalInt.Some would be Int -> Option Int, but importing OptionalInt would bring Some : forall a . a -> Option a into scope as well.

Edit: Clicking the right button is hard, I didn't mean to close this issue :D

@Laegluin Laegluin reopened this Jun 20, 2018
@Marwes
Copy link
Member

Marwes commented Jun 24, 2018

Yep, that seems like a good compromise. I will look into always exporting the variant as the generic type. It is probably just a 1 line change in the typechecker

@Laegluin
Copy link
Contributor Author

Yep, that seems like a good compromise. I will look into always exporting the variant as the generic type. It is probably just a 1 line change in the typechecker

Yeah, it doesn't seem like a lot of work, but when I tried yesterday I failed miserably, so I'll better leave this to you :p

@Marwes
Copy link
Member

Marwes commented Jun 26, 2018

A bit more awkward of a solution than I had hoped as there were some annoying edge cases to consider. I may revisit precisely how this works after scoped constructors and more precise control on which constructors gets added.

bors bot added a commit that referenced this issue Jun 26, 2018
557: fix(check): Don't shadow more general variant constructors r=Marwes a=Marwes

Fixes #548

Co-authored-by: Markus Westerlind <marwes91@gmail.com>
@bors bors bot closed this as completed in #557 Jun 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants