Improving Haskell (GHC) Error Messages

by Marc Scholten, 20.12.2020

The quality of GHC's error messages is making it harder for newcomers to adopt Haskell. A good error message should be clear, actionable, and practical. In this aspect GHC could be a lot more user-friendly.

Here's an example related to type-level-list syntax that often comes up in the IHP community:

action CreateUserAction = do
        let user = newRecord @User
        let password = param @Text "password"
        user
            |> set #passwordHash password
            |> fill @["email"]
            |> validateField #email isEmail
            |> validateField #passwordHash nonEmpty
            |> debug
            |> ifValid \case
            Left user ->
                render NewView {..}
            Right user -> do
                hashed <- hashPassword (get #passwordHash user)
                user
                    |> set #passwordHash hashed
                    |> createRecord

                setSuccessMessage "You have successfully registered"

This code snippet errors with:

Web/Controller/Users.hs:16:23
    * Expected a type, but `"email"' has kind `Symbol'
    * In the type `["email"]'
      In the second argument of `(|>)', namely `fill @["email"]'
      In the first argument of `(|>)', namely
        `user |> set #passwordHash password |> fill @["email"]'
   |
16 |             |> fill @["email"]
   |                       ^^^^^^^

Unless you know about the type-level-list syntax issue with ' you will most likely get stuck.

A better error message could offer a solution that will most likely help:

Web/Controller/Users.hs:16:23
    * Type level lists with only a single element need a ' in front of the list. Prepend a ' like `'["email]' to get it working.
    * In the type `["email"]'
      In the second argument of `(|>)', namely `fill @["email"]'
      In the first argument of `(|>)', namely
        `user |> set #passwordHash password |> fill @["email"]'
   |
16 |             |> fill @["email"]
   |                       ^^^^^^^

We've collected a couple more real-world issues on GitHub with possible better alternatives.

I'd like to start a discussion in the larger haskell community on this so we can find a process on how we can improve this longterm. E.g. maybe we could have a central repository where haskell users could report bad and unclear error messages.

There's haskell/rfcs for new GHC features, so why don't we have a repository like haskell/ux where we can collect ideas to improve existing features?

Let me know what you think about this on GitHub or Reddit.