elm / error-message-catalog

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

Type mismatch reports same types (value is a Int -> Model but needs to be Int -> Model) #278

Closed andybalaam closed 5 years ago

andybalaam commented 5 years ago
$ elm --version
0.19.0

I am told there is a TYPE MISMATCH, but the types being reported are identical.

I've tried to reduce it to a small example:

src/SameType.elm:

module SameType exposing (..)

import Browser.Events as Events
import Json.Decode as D

type alias Model =
    { x : Int
    , y : Int
    }

makeModel : Int -> Int -> Model
makeModel x y =
    { x = x, y = y }

type Msg =
    MouseChange Model

mmDecoder : D.Decoder Msg
mmDecoder =
    D.map2
        (MouseChange << makeModel)
        (D.field "x" D.int)
        (D.field "y" D.int)

subscriptions : Model -> Sub Msg
subscriptions model =
    Events.onMouseMove mmDecoder

Here is the compile error:

$ elm make src/SameType.elm 
Detected errors in 1 module.                                         
-- TYPE MISMATCH ---------------------------------------------- src/SameType.elm

The 1st argument to `map2` is not what I expect:

25|     D.map2
26|>        (MouseChange << makeModel)
27|         (D.field "x" D.int)
28|         (D.field "y" D.int)

This argument is:

    Int -> Msg

But `map2` needs the 1st argument to be:

    Int -> value

-- TYPE MISMATCH ---------------------------------------------- src/SameType.elm

The right argument of (<<) is causing problems.

26|         (MouseChange << makeModel)
                            ^^^^^^^^^
This `makeModel` value is a:

    Int -> Model

But (<<) needs the right argument to be:

    Int -> Model

Hint: With operators like (<<) I always check the left side first. If it seems
fine, I assume it is correct and check the right side. So the problem may be in
how the left and right arguments interact!

Note that the two types (expected and actual) for the right argument of << are both Int -> Model.

andybalaam commented 5 years ago

By the way, I found a way to get the above code to compile. I replaced the line:

(MouseChange << makeModel)

with:

(\x y -> MouseChange <| makeModel x y)

which demonstrates the error: makeModel takes two arguments.

evancz commented 5 years ago

Thank you for the report! I believe this bug got introduced with 0.19.0 and was fixed in https://github.com/elm/compiler/commit/a5febad184588ae79b404d22a020020408580041, so my development build is currently saying:

-- TYPE MISMATCH ------------------------------------------------------ temp.elm

The 1st argument to `map2` is not what I expect:

20|     D.map2
21|>        (MouseChange << makeModel)
22|         (D.field "x" D.int)
23|         (D.field "y" D.int)

This argument is:

    Int -> Msg

But `map2` needs the 1st argument to be:

    Int -> b -> value

Hint: It looks like it takes too few arguments. I was expecting 1 more.

-- TYPE MISMATCH ------------------------------------------------------ temp.elm

The right argument of (<<) is causing problems.

21|         (MouseChange << makeModel)
                            ^^^^^^^^^
This `makeModel` value is a:

    Int -> Int -> Model

But (<<) needs the right argument to be:

    Int -> Model

Hint: With operators like (<<) I always check the left side first. If it seems
fine, I assume it is correct and check the right side. So the problem may be in
how the left and right arguments interact!

Hint: It looks like it takes too many arguments. I see 1 extra.

So it looks like the fix is working in your case as well. The fix will be available once Elm 0.19.1 is released!

andybalaam commented 5 years ago

Fantastic, thank you!