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 with identical types displayed #285

Closed nagdon closed 5 years ago

nagdon commented 5 years ago

The following two REPL commands produce an incorrect and confusing error message:

> sorter x = (String.toInt x, x)
<function> : String -> ( Maybe Int, String )
> List.sortBy sorter [ "9", "10", "a", "1a" ]
-- TYPE MISMATCH ----------------------------------------------------------- elm

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

6|   List.sortBy sorter [ "9", "10", "a", "1a" ]
                 ^^^^^^
This `sorter` value is a:

    String -> ( Maybe Int, String )

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

    String -> ( Maybe Int, String )

The real cause of the error is that Maybe is not a comparable type. I would guess that this is not the same problem as the one reported in #278, but I didn't try to find the cause in the complier sources.

maxf commented 5 years ago

The following REPL code produces a similar error (seems related so not opening a new issue):

import Url
import Url.Parser exposing ((</>), (<?>), string, fragment, top, parse)
import Url.Parser.Query as Query

urlParser = top <?> Query.string "code" </> fragment identity
url = Url.Url Https.Https "example.org" Nothing "" Nothing Nothing
parse urlParser url
-- TYPE MISMATCH ----------------------------------------------------------- elm

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

9|   parse urlParser url
           ^^^^^^^^^
This `urlParser` value is a:

    Url.Parser.Parser (Maybe String -> Maybe String) (Maybe String)

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

    Url.Parser.Parser (Maybe String -> Maybe String) (Maybe String)
evancz commented 5 years ago

I fixed this with https://github.com/elm/compiler/commit/545b1784695500e822c2d044b6b5ed2ab6689552, so my development build is now showing the following:

---- Elm 0.19.1 ----------------------------------------------------------------
Say :help for help and :exit to exit! More at <https://elm-lang.org/0.19.1/repl>
--------------------------------------------------------------------------------
> sorter x = (String.toInt x, x)
<function> : String -> ( Maybe Int, String )
> List.sortBy sorter [ "9", "10", "a", "1a" ]
-- TYPE MISMATCH ---------------------------------------------------------- REPL

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

4|   List.sortBy sorter [ "9", "10", "a", "1a" ]
                 ^^^^^^
This `sorter` value is a:

    String -> ( Maybe Int, String )

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

    String -> comparable

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

I think it's possible to do a bit better on the hint. Hopefully mention Maybe not being comparable explicitly. I'll give it a shot at least!

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!