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

Error message suggests the same type as the value that's passed in, should suggest it needs a comparable #274

Closed alex-tan closed 5 years ago

alex-tan commented 5 years ago

At least, I think that's the issue:

module Main exposing (groupBy)

import Dict exposing (Dict)

groupBy : (a -> comparable) -> List a -> Dict comparable (List a)
groupBy groupFn a =
    Dict.empty

type alias Modification =
    { objectName : String
    , objectNumber : Maybe String
    , attributeName : String
    }

type alias ConflictsForPath = 
    Dict (String, Maybe String, String) (List (Int, Modification))

type alias AllModificationsForPath = List (Int, Modification )

getConflicts : AllModificationsForPath -> ConflictsForPath
getConflicts all =
    all |> groupBy (Tuple.second >> objectAttributeKey)

objectAttributeKey : Modification -> (String, Maybe String, String)
objectAttributeKey m = 
    (m.objectName, m.objectNumber, m.attributeName)

Ellie

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

24|     all |> groupBy (Tuple.second >> objectAttributeKey)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This argument is:

    ( a, Modification ) -> ( String, Maybe String, String )

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

    ( a, Modification ) -> ( String, Maybe String, String )

As you can see it says the argument is one thing, but is the same thing it suggests it to be.

The issue seems to be that Maybe isn't comparable, which causes the error. If the Maybe value is removed from the tuple the code compiles.

evancz commented 5 years ago

I made a fix for this in https://github.com/elm/compiler/commit/545b1784695500e822c2d044b6b5ed2ab6689552, so my development build is now producing:

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

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

21|     all |> groupBy (Tuple.second >> objectAttributeKey)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The body is:

    Dict comparable (List ( Int, Modification ))

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

    ConflictsForPath

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

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

21|     all |> groupBy (Tuple.second >> objectAttributeKey)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This argument is:

    ( a, Modification ) -> ( String, Maybe String, String )

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

    ( a, Modification ) -> comparable

Hint: Only ints, floats, chars, strings, lists, and tuples are comparable.

I think it's possible to do better on the hint though. I'll give it a shot!

evancz commented 5 years ago

I tried making the hint really extra specific, but I ended up needing to rewrite some code that would be a bit too risky to change this close to a release. I ended up with some logic that should improve the hints on comparable clashes, but not in cases where a comparable constraint is having trouble with a type within a list or tuple.

Anyway, thank you for reporting the error here!