Can't solve constraints in values which came from constructor binders where the constructor was polymorphic by jy14898 · Pull Request #4196 · purescript/purescript · GitHub
Skip to content

Can't solve constraints in values which came from constructor binders where the constructor was polymorphic - #4196

Open
jy14898 wants to merge 3 commits into
purescript:masterfrom
jy14898:SubstVarsBeforeSubsumptionInTypeChecking
Open

jy14898 wants to merge 3 commits into
purescript:masterfrom
jy14898:SubstVarsBeforeSubsumptionInTypeChecking

Conversation

@jy14898

@jy14898 jy14898 commented Nov 1, 2021 •

Copy link
Copy Markdown
Contributor

Before this change, you couldn't solve constraints in values which came from constructor binders where the constructor was polymorphic:

class Con

newtype Identity a = Identity a

-- works
test1 :: Con => (Con => Int) -> Int
test1 a = a

-- fails
test2 :: Con => Identity (Con => Int) -> Int
test2 (Identity a) = a

This is because we weren't applying substitutions when checking the types of 'Var' exprs before subsumption, and polymorphic types like Identity get instantiated with unknowns during binder inference. This change adds the substitution in.

Checklist:

  • Added a file to CHANGELOG.d for this PR (see CHANGELOG.d/README.md)
  • Added myself to CONTRIBUTORS.md (if this is my first contribution)
  • Linked any existing issues or proposals that this pull request should close
  • Updated or added relevant documentation
  • Added a test for the contribution (if applicable)

@garyb garyb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of a reason why there would be a problem doing this. Those revised error output seem like improvements too! 👍

@rhendric

rhendric commented Nov 5, 2021

Copy link
Copy Markdown
Member

@jy14898

jy14898 commented Nov 5, 2021

Copy link
Copy Markdown
Contributor Author

How exactly does this get used?

Good point, originally I was just messing around with deferring execution of expressions automatically (similar to https://github.com/natefaubion/purescript-call-by-name I believe), and found it surprising that using Identity would not work.

I was using FFI to construct these values which meant I never actually tested creating them in-language.

I'll have a look to see if it makes sense to allow constructing such values naturally

@jy14898

jy14898 commented Nov 7, 2021 •

Copy link
Copy Markdown
Contributor Author

@rhendric It's possible, although you have to be explicit about the type of Identity when constructing it:

-- compiles fine in the pull req, with inferred type Con => Int
test2' = test2 ((Identity :: (Con => Int) -> Identity (Con => Int)) 10)

The changes required to not need that hint are too great, I think

It's actually possible to write the original test2 with hints that works without the PR, although it'd defeat the purpose of my original use, which was to have such a function be simple to write:

test2 :: Con => Identity (Con => Int) -> Int
test2 (Identity (a :: Con => Int)) = a

@rhendric

rhendric commented Nov 7, 2021

Copy link
Copy Markdown
Member

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

Successfully merging this pull request may close these issues.

3 participants