elm / compiler

Compiler for Elm, a functional language for reliable webapps.
https://elm-lang.org/
BSD 3-Clause "New" or "Revised" License
7.51k stars 656 forks source link

Type variables don't unify correctly in top level declarations #2186

Open davidcavazos opened 3 years ago

davidcavazos commented 3 years ago

Hi, I found an inconsistency while unifying type variables.

SSCCE

This works as expected, the type a unifies with type b and we don't get any errors.

k : Int
k =
  let
    f : a -> Int
    f x = 1

    g : b -> Int
    g = f
  in
  42

However, if the type variable was defined at the top-level declaration, we get a type error.

f : a -> Int
f x =
  let
    g : b -> Int
    g = f
  in
  42

Here's the error:

Something is off with the body of the `g` definition:

8|     g = f
           ^
This `f` value is a:

    a -> Int

But the type annotation on `g` says it should be:

    b -> Int

I think b should be able to unify with a without any problems.

Workaround: creating an "identity" copy of the function.

f : a -> Int
f x =
  42

g : b -> Int
g = f

Additional Details

That's a pretty stripped down example to reproduce the error, but this issue has been pretty annoying in my code base since I have to be declaring "duplicate" top-level wrapper functions with specialized types to calm down the type checker. Since my functions were recursive, I basically had to create a copy of the function with an underscore suffix and use that. It took a while to strip it down to a single function :)

github-actions[bot] commented 3 years ago

Thanks for reporting this! To set expectations:

Finally, please be patient with the core team. They are trying their best with limited resources.