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

Can't unify two equal type literals in some cases #4543

Open
Renegatto opened this issue May 13, 2024 · 0 comments
Open

Can't unify two equal type literals in some cases #4543

Renegatto opened this issue May 13, 2024 · 0 comments

Comments

@Renegatto
Copy link

Description

It seems that in some cases compiler does not recognize that "(foo" :: Symbol) ~ ("foo" :: Symbol) in presence of row types and their magic constraints.

To Reproduce

Consider the code

class TypeEquals a b | a -> b, b -> a
instance TypeEquals a a


fn :: forall label a r r'. 
  Cons label a r r' =>
  Proxy label ->
  Record r -> 
  Record r'
fn = unsafeThrow "not implemented"

These functions do not typecheck:

  1. Cons "foo"; Proxy "foo"
  2. Cons foo; Proxy "foo"
  3. Cons "foo"; Proxy foo
bothLiterals :: forall a r r'.
  Cons "foo" a r r' =>
  Record r ->
  Record r'
bothLiterals r =
  fn (Proxy :: _ "foo") r -- fails
Type error
  Could not match type

    ( foo :: t1
    | r4
    )

  with type

    r'5
proxyLiteral :: forall a r r' foo.
  TypeEquals foo "foo" =>
  Cons foo a r r' =>
  Record r ->
  Record r'
proxyLiteral r =
  fn (Proxy :: _ "foo") r -- fails
Type error
  Could not match type

    ( foo :: t1
    | r4
    )

  with type

    r'5
consLiteral :: forall a r r' foo.
  TypeEquals foo "foo" =>
  Cons "foo" a r r' =>
  Record r ->
  Record r'
consLiteral r = fn (Proxy :: _ foo) r -- fails
Type error
  No type class instance was found for

    Prim.Row.Cons foo4
                  t1
                  r5
                  r'6

And this one typechecks:

  • Cons foo; Proxy foo
onlyTyVars :: forall a r r' foo.
  TypeEquals foo "foo" =>
  Cons foo a r r' =>
  Record r ->
  Record r'
onlyTyVars r = fn (Proxy :: _ foo) r

Expected behavior

Either all the examples cases typecheck well, or none of them do.

Additional context

Note, that if any of the functions was implemented, it would work well with foo ~ "foo". For instance this typechecks well:

f :: forall a r.
  Record r ->
  Record (foo :: a | r)
f = consLiteral -- using one of the functions that didn't typecheck

PureScript version

0.15.8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant