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

Typechecker fails to unify #842

Closed
omegablitz opened this issue Jun 9, 2020 · 1 comment · Fixed by #899
Closed

Typechecker fails to unify #842

omegablitz opened this issue Jun 9, 2020 · 1 comment · Fixed by #899

Comments

@omegablitz
Copy link
Contributor

I finally got around to implementing an immutable vector type (#472). While implementing it, I ran into a case where the typechecker fails to unify, when it should.

Condensed example:

type Digit a =
    | One a
    | Two a a
    | Three a a a
    | Four a a a a

type Node a =
    | Node2 a a
    | Node3 a a a

type FingerTree a =
    | Empty
    | Single a
    | Deep (Digit a) (FingerTree (Node a)) (Digit a)

type View a =
    | Nil
    | View a (FingerTree a)

rec
let viewl xs : FingerTree a -> View a =
    match xs with
    | Empty -> Nil
    | Single x -> View x Empty
    | Deep (One a) deeper suffix ->
        match viewl deeper with
        | View (Node2 b c) rest -> View a (Deep (Two b c) rest suffix)
        | View (Node3 b c d) rest -> View a (Deep (Three b c d) rest suffix)
        | Nil ->
            match suffix with
            | One w -> View a (Single w)
            | Two w x -> View a (Deep (One w) Empty (One x))
            | Three w x y -> View a (Deep (Two w x) Empty (One y))
            | Four w x y z -> View a (Deep (Three w x y) Empty (One z))
    | Deep (Two a b) deeper suffix -> View a (Deep (One b) deeper suffix)
    | Deep (Three a b c) deeper suffix -> View a (Deep (Two b c) deeper suffix)
    | Deep (Four a b c d) deeper suffix -> View a (Deep (Three b c d) deeper suffix)
in

viewl

The specific lines the typechecker doesn't seem to like are lines 28 - 34, but am not sure for what reason. Full error:

error: Expected the following types to be equal
Expected: .tmp.test.FingerTree a
Found: .tmp.test.FingerTree a
1 errors were found during unification:
Types do not match:
    Expected: a
    Found: a
- <.tmp.test>:28:46
   |
28 |         | View (Node3 b c d) rest -> View a (Deep (Three b c d) rest suffix)
   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |

error: Expected the following types to be equal
Expected: .tmp.test.FingerTree a
Found: .tmp.test.FingerTree a
1 errors were found during unification:
Types do not match:
    Expected: a
    Found: a
- <.tmp.test>:31:32
   |
31 |             | One w -> View a (Single w)
   |                                ^^^^^^^^
   |

error: Expected the following types to be equal
Expected: .tmp.test.FingerTree a
Found: .tmp.test.FingerTree a
1 errors were found during unification:
Types do not match:
    Expected: a
    Found: a
- <.tmp.test>:32:34
   |
32 |             | Two w x -> View a (Deep (One w) Empty (One x))
   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |

error: Expected the following types to be equal
Expected: .tmp.test.FingerTree a
Found: .tmp.test.FingerTree a
1 errors were found during unification:
Types do not match:
    Expected: a
    Found: a
- <.tmp.test>:33:38
   |
33 |             | Three w x y -> View a (Deep (Two w x) Empty (One y))
   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |

error: Expected the following types to be equal
Expected: .tmp.test.FingerTree a
Found: .tmp.test.FingerTree a
1 errors were found during unification:
Types do not match:
    Expected: a
    Found: a
- <.tmp.test>:34:39
   |
34 |             | Four w x y z -> View a (Deep (Three w x y) Empty (One z))
   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |

@Shuenhoy
Copy link
Contributor

This may be helpful to figure out the reason. Use different variables in each place:

type Digit a =
    | One a
    | Two a a
    | Three a a a
    | Four a a a a

type Node b =
    | Node2 b b
    | Node3 b b b

type FingerTree c =
    | Empty
    | Single c
    | Deep (Digit c) (FingerTree (Node c)) (Digit c)

type View d =
    | Nil
    | View d (FingerTree d)

rec
let viewl xs : FingerTree e -> View e =
    match xs with
    | Empty -> Nil
    | Single x -> View x Empty
    | Deep (One a) deeper suffix ->
        match viewl deeper with
        | View (Node2 b c) rest -> View a (Deep (Two b c) rest suffix)
        | View (Node3 b c d) rest -> View a (Deep (Three b c d) rest suffix)
        | Nil ->
            match suffix with
            | One w -> View a (Single w)
            | Two w x -> View a (Deep (One w) Empty (One x))
            | Three w x y -> View a (Deep (Two w x) Empty (One y))
            | Four w x y z -> View a (Deep (Three w x y) Empty (One z))
    | Deep (Two a b) deeper suffix -> View a (Deep (One b) deeper suffix)
    | Deep (Three a b c) deeper suffix -> View a (Deep (Two b c) deeper suffix)
    | Deep (Four a b c d) deeper suffix -> View a (Deep (Three b c d) deeper suffix)
in

viewl

The error would become:

error: Expected the following types to be equal
Expected: test.FingerTree e
Found: test.FingerTree c
1 errors were found during unification:
Types do not match:
    Expected: e
    Found: c
   ┌─ test:28:46
   │
28 │         | View (Node3 b c d) rest -> View a (Deep (Three b c d) rest suffix)
   │                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


error: Expected the following types to be equal
Expected: test.FingerTree e
Found: test.FingerTree c
1 errors were found during unification:
Types do not match:
    Expected: e
    Found: c
   ┌─ test:31:32
   │
31 │             | One w -> View a (Single w)
   │                                ^^^^^^^^


error: Expected the following types to be equal
Expected: test.FingerTree e
Found: test.FingerTree c
1 errors were found during unification:
Types do not match:
    Expected: e
    Found: c
   ┌─ test:32:34
   │
32 │             | Two w x -> View a (Deep (One w) Empty (One x))
   │                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^


error: Expected the following types to be equal
Expected: test.FingerTree e
Found: test.FingerTree c
1 errors were found during unification:
Types do not match:
    Expected: e
    Found: c
   ┌─ test:33:38
   │
33 │             | Three w x y -> View a (Deep (Two w x) Empty (One y))
   │                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^


error: Expected the following types to be equal
Expected: test.FingerTree e
Found: test.FingerTree c
1 errors were found during unification:
Types do not match:
    Expected: e
    Found: c
   ┌─ test:34:39
   │
34 │             | Four w x y z -> View a (Deep (Three w x y) Empty (One z))
   │               

bors bot added a commit that referenced this issue Dec 25, 2020
899:  fix: Don't refine already refined skolems r=Marwes a=Marwes

Fixes #842



Co-authored-by: Markus Westerlind <marwes91@gmail.com>
@bors bors bot closed this as completed in f39b396 Dec 25, 2020
Marwes added a commit to Marwes/gluon that referenced this issue Oct 3, 2021
<a name="v0.18.0"></a>
## v0.18.0 (2021-10-03)

#### Bug Fixes

*   Don't use the empty span in derive macros ([d05f1ca](gluon-lang@d05f1ca))
*   Provide the type of imported modules with errors ([d3bfc59](gluon-lang@d3bfc59))
*   Don't refine already refined skolems ([f39b396](gluon-lang@f39b396), closes [gluon-lang#842](gluon-lang#842))
*   Recognize raw string literals without any `#` ([4d66fbb](gluon-lang@4d66fbb), closes [gluon-lang#885](gluon-lang#885))
*   Prevent zero-argument functions from being created in Rust ([e91ea06](gluon-lang@e91ea06), closes [gluon-lang#873](gluon-lang#873))
*   Give tuple fields a span ([2a1c2c7](gluon-lang@2a1c2c7))
*   xor_shift_new inconsistent description ([591b64b](gluon-lang@591b64b))

#### Performance

*   Avoid recreating the vm for each formatted file ([0335733](gluon-lang@0335733))

#### Features

*   Make channels and reference require IO ([c904189](gluon-lang@c904189), breaks [#](https://github.com/gluon-lang/gluon/issues/))
*   Allow specifying type signatures in do bindings ([fac08dc](gluon-lang@fac08dc))
*   Allow macros to refer to symbols in scope at the expansion site ([1a5489c](gluon-lang@1a5489c), closes [gluon-lang#895](gluon-lang#895))
*   Allow the http module to be used without a tcp listener ([c45353d](gluon-lang@c45353d))
*   Format seq expressions without seq ([5c0cec2](gluon-lang@5c0cec2))
*   Compile block expressions as monadic sequences ([bce5973](gluon-lang@bce5973), closes [gluon-lang#884](gluon-lang#884))
* **std:**
  *  add Option assertions to std.test ([28e5053](gluon-lang@28e5053))
  *  add modulo functions to int and float ([92f188a](gluon-lang@92f188a))

#### Breaking Changes

*   Make channels and reference require IO ([c904189](gluon-lang@c904189), breaks [#](https://github.com/gluon-lang/gluon/issues/))
Marwes added a commit to Marwes/gluon that referenced this issue Oct 3, 2021
<a name="v0.18.0"></a>
## v0.18.0 (2021-10-03)

#### Performance

*   Avoid recreating the vm for each formatted file ([0335733](gluon-lang@0335733))

#### Breaking Changes

*   Make channels and reference require IO ([c904189](gluon-lang@c904189), breaks [#](https://github.com/gluon-lang/gluon/issues/))

#### Features

*   Make channels and reference require IO ([c904189](gluon-lang@c904189), breaks [#](https://github.com/gluon-lang/gluon/issues/))
*   Allow specifying type signatures in do bindings ([fac08dc](gluon-lang@fac08dc))
*   Allow macros to refer to symbols in scope at the expansion site ([1a5489c](gluon-lang@1a5489c), closes [gluon-lang#895](gluon-lang#895))
*   Allow the http module to be used without a tcp listener ([c45353d](gluon-lang@c45353d))
*   Format seq expressions without seq ([5c0cec2](gluon-lang@5c0cec2))
*   Compile block expressions as monadic sequences ([bce5973](gluon-lang@bce5973), closes [gluon-lang#884](gluon-lang#884))
* **std:**
  *  add Option assertions to std.test ([28e5053](gluon-lang@28e5053))
  *  add modulo functions to int and float ([92f188a](gluon-lang@92f188a))

#### Bug Fixes

*   Allow the repl to compile concurrently ([2118f4d](gluon-lang@2118f4d))
*   Don't use the empty span in derive macros ([d05f1ca](gluon-lang@d05f1ca))
*   Provide the type of imported modules with errors ([d3bfc59](gluon-lang@d3bfc59))
*   Don't refine already refined skolems ([f39b396](gluon-lang@f39b396), closes [gluon-lang#842](gluon-lang#842))
*   Recognize raw string literals without any `#` ([4d66fbb](gluon-lang@4d66fbb), closes [gluon-lang#885](gluon-lang#885))
*   Prevent zero-argument functions from being created in Rust ([e91ea06](gluon-lang@e91ea06), closes [gluon-lang#873](gluon-lang#873))
*   Give tuple fields a span ([2a1c2c7](gluon-lang@2a1c2c7))
*   xor_shift_new inconsistent description ([591b64b](gluon-lang@591b64b))
bors bot added a commit that referenced this issue Oct 3, 2021
915: Version 0.18.0 r=Marwes a=Marwes

<a name="v0.18.0"></a>
## v0.18.0 (2021-10-03)

#### Performance

*   Avoid recreating the vm for each formatted file ([0335733](0335733))

#### Breaking Changes

*   Make channels and reference require IO ([c904189](c904189), breaks [#](https://github.com/gluon-lang/gluon/issues/))

#### Features

*   Make channels and reference require IO ([c904189](c904189), breaks [#](https://github.com/gluon-lang/gluon/issues/))
*   Allow specifying type signatures in do bindings ([fac08dc](fac08dc))
*   Allow macros to refer to symbols in scope at the expansion site ([1a5489c](1a5489c), closes [#895](#895))
*   Allow the http module to be used without a tcp listener ([c45353d](c45353d))
*   Format seq expressions without seq ([5c0cec2](5c0cec2))
*   Compile block expressions as monadic sequences ([bce5973](bce5973), closes [#884](#884))
* **std:**
  *  add Option assertions to std.test ([28e5053](28e5053))
  *  add modulo functions to int and float ([92f188a](92f188a))

#### Bug Fixes

*   Allow the repl to compile concurrently ([2118f4d](2118f4d))
*   Don't use the empty span in derive macros ([d05f1ca](d05f1ca))
*   Provide the type of imported modules with errors ([d3bfc59](d3bfc59))
*   Don't refine already refined skolems ([f39b396](f39b396), closes [#842](#842))
*   Recognize raw string literals without any `#` ([4d66fbb](4d66fbb), closes [#885](#885))
*   Prevent zero-argument functions from being created in Rust ([e91ea06](e91ea06), closes [#873](#873))
*   Give tuple fields a span ([2a1c2c7](2a1c2c7))
*   xor_shift_new inconsistent description ([591b64b](591b64b))

Co-authored-by: Markus Westerlind <marwes91@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants