elm / error-message-catalog

A catalog of broken Elm programs / data to improve error messages
BSD 3-Clause "New" or "Revised" License
174 stars 17 forks source link

Types should be realiased in error messages #43

Closed zgotsch closed 8 years ago

zgotsch commented 9 years ago

I am working through the Elm architecture tutorial and I was getting an unhelpful unification error message from the compiler. When reporting the expected types and the encountered type, they did not match what I expected from the code.

Here is the code which is causing the error:

type Action
  = Reset
  | AddCounter
  | RemoveCounter
  | Update CounterId Counter.Action

type alias CounterId = Int

type alias Model =
  { counters : List (CounterId, Counter.Model)
  , nextId : CounterId
  }

update : Action -> Model -> Model
update action model =
  case action of
    Update id act -> { model |
      counters <- (List.map
        (\(i, model) ->
          if | i == id -> Counter.update act model
             | otherwise -> model)
        model.counters)
      }

The lambda is returning a Counter.Model when it should be returning a (CounterId, Counter.Model), but the error message says:

-- TYPE MISMATCH ------------------------------------------- ././CounterList.elm

The 2nd branch of this `case` results in an unexpected type of value.

37|   case action of
38|     Reset -> init 0 3
39|     -- AddCounter -> { counters = (model.nextId, Counter.init 0)
40|     --               , nextId = model.nextId + 1
41|     --               }
42|     -- RemoveCounter -> case model.counters of
43|     --   hd::tl -> { counters = tl
44|     --             , nextId = model.nextId - 1
45|     --             }
46|     --   [] -> model
47|>    Update id act -> { model |
48|>      counters <- (List.map
49|>        (\(i, model) ->
50|>          if | i == id -> Counter.update act model
51|>             | otherwise -> model)
52|>        model.counters)
53|>      }

All branches should match so that no matter which one we take, we always get
back the same type of value.

As I infer the type of values flowing through your program, I see a conflict
between these two types:

    (Int, Int)

    Int

I don't understand why it is saying (Int, Int) and Int in the error message, instead of (CounterId, Counter.Model) and Counter.Model. Fixing the type of the lambda causes these messages to disappear.

P.S. There is also an error for the function not matching the signature which gives the same types:

-- TYPE MISMATCH ------------------------------------------- ././CounterList.elm

The type annotation for `update` does not match its definition.

35| update : Action -> Model -> Model
             ^^^^^^^^^^^^^^^^^^^^^^^^
As I infer the type of values flowing through your program, I see a conflict
between these two types:

    (Int, Int)

    Int
zgotsch commented 9 years ago

Moved from https://github.com/elm-lang/elm-compiler/issues/1062#issuecomment-141540911

evancz commented 8 years ago

In 0.18, we do a much better job of preserving type aliases into error messages, so I think the best path forward is to trust that it is fixed and if you see the behavior again, open a new issue with an http://sscce.org so I can test things.