# Beginner thought process on type mismatch error

**URL:** <https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415>\
**Category:** Learn\
**Created:** [April 2, 2020, 2:23am UTC](https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415 "2020-04-02T02:23:20Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![francois](https://avatars.discourse-cdn.com/v4/letter/f/77aa72/32.png) [@francois](https://discourse.elm-lang.org/u/francois)\
**Post date:** [April 2, 2020, 2:23am UTC](https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415/1 "2020-04-02T02:23:20Z")

</div>

Hi all!

I’m a beginner Elm programmer. I saw elm-ui mentioned on Hacker News lately, and I wanted to try it. As I built a toy page, I stumbled upon a type mismatch error that I had difficulty understanding, but which I ultimately managed to resolve by myself.

The type mismatch error was:

```auto
-- TYPE MISMATCH ------------ /Users/francois/Projects/elm/scoutges/src/Main.elm

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

111|> row []
112|> [search []
113|> { text = queryString model
114|> , placeholder = Just (placeholder [] (text "Type your query..."))
115|> , label = labelHidden "Search"
116|> , onChange = \q -> SearchFor q
117|> }
118|> ]

This `row` call produces:

    Element Msg

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

    Element msg

```

in the following code:

```auto
module Main exposing (..)

import Browser
import Browser.Navigation as Nav
import Element exposing (Element, alignRight, alignTop, centerY, el, fill, link, padding, rgb255, row, spacing, text, width)
import Element.Background as Background
import Element.Border as Border
import Element.Font as Font
import Element.Input exposing (labelHidden, placeholder, search)
import Html exposing (Html)
import Url

-- MAIN

main : Program () Model Msg
main =
    Browser.application
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        , onUrlChange = UrlChanged
        , onUrlRequest = LinkClicked
        }

-- MODEL

type alias Model =
    { key : Nav.Key
    , url : Url.Url
    , query : Maybe String
    }

init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
init flags url key =
    ( Model key url Nothing, Cmd.none )

-- UPDATE

type Msg
    = LinkClicked Browser.UrlRequest
    | UrlChanged Url.Url
    | SearchFor String

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        LinkClicked urlRequest ->
            case urlRequest of
                Browser.Internal url ->
                    ( model, Nav.pushUrl model.key (Url.toString url) )

                Browser.External href ->
                    ( model, Nav.load href )

        UrlChanged url ->
            ( { model | url = url }
            , Cmd.none
            )

        SearchFor q ->
            ( { model | query = Just q }
            , Cmd.none
            )

-- SUBSCRIPTIONS

subscriptions : Model -> Sub Msg
subscriptions _ =
    Sub.none

-- VIEW

view : Model -> Browser.Document Msg
view model =
    { title = "URL Interceptor"
    , body =
        [Element.layout [] (navBarView model) ]
    }

navBarView : Model -> Element msg
navBarView model =
    row []
        [el [ alignRight] (searchView model)
        ]

searchView : Model -> Element msg
searchView model =
    row []
        [search []
            { text = ""
            , placeholder = Just (placeholder [] (text "Type your query..."))
            , label = labelHidden "Search"
            , onChange = \q -> SearchFor q
            }
        ]

```

Initially, I suspected that the problem stemmed from the onChange lambda. It was the only thing in `searchView` that dealt with `Msg` at all. `search`'s type is:

```auto
search :
    List (Attribute msg)
    -> { onChange : String -> msg
       , text : String
       , placeholder : Maybe (Placeholder msg)
       , label : Label msg
       }
    -> Element msg

```

When I changed my code to:

```auto
searchView : Model -> Element msg
searchView model =
    row []
        [search []
            { text = ""
            , placeholder = Just (placeholder [] (text "Type your query..."))
            , label = labelHidden "Search"
            , onChange = searchQuery
            }
        ]

searchQuery : String -> msg
searchQuery q =
    SearchFor q

```

then I received a different type mismatch error:

```auto
-- TYPE MISMATCH ------------ /Users/francois/Projects/elm/scoutges/src/Main.elm

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

123| SearchFor q
         ^^^^^^^^^^^
This `SearchFor` call produces:

    Msg

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

    msg

```

As I was writing this message to ask for help, and reading examples on elm-ui, I thought of using this:

```auto
searchView : Model -> Element msg
searchView model =
    row []
        [search []
            { text = ""
            , placeholder = Just (placeholder [] (text "Type your query..."))
            , label = labelHidden "Search"
            , onChange = SearchFor
            }
        ]

```

But this returned the same type error as the 1st attempt.

I both FAQ entries [What’s the difference between Html Msg and Html msg?](http://faq.elm-community.org/#whats-the-difference-between-html-msg-and-html-msg) and [What’s the difference between Cmd Msg and Cmd msg?](http://faq.elm-community.org/#what-is-the-difference-between-cmd-msg-and-cmd-msg). I can read some Haskell, and I believe I understand type “holes”, but I really, really didn’t understand what was the problem in this code.

Re-reading the elm-ui page for Element.Input, I found the following example for checkboxes:

```auto
import Element exposing (text)
import Element.Input as Input

type Msg
    = GuacamoleChecked Bool

view model =
    Input.checkbox []
        { onChange = GuacamoleChecked
        , icon = Input.defaultCheckbox
        , checked = model.guacamole
        , label =
            Input.labelRight []
                (text "Do you want Guacamole?")
        }

```

To my untrained eye, this was the same as my last example. This example does not have a type annotation, but even then, it is the example that unblocked me. I changed my type annotations from:

```auto
searchView : Model -> Element msg

```

to

```auto
searchView : Model -> Element Msg

```

throughout my code. Lo and behold, it finally worked! My code is a straight copy/paste of Web Apps Navigation Example, modified to add some UI elements.

I think that when I wrote new functions, I used the following type annotation as my guide:

```auto
viewLink : String -> Html msg

```

This is the type annotation that is written in the Navigation Example.

I was also confused by the 1st error message I received:

```auto
-- TYPE MISMATCH ------------ /Users/francois/Projects/elm/scoutges/src/Main.elm

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

111|> row []
112|> [search []
113|> { text = queryString model
114|> , placeholder = Just (placeholder [] (text "Type your query..."))
115|> , label = labelHidden "Search"
116|> , onChange = \q -> SearchFor q
117|> }
118|> ]

This `row` call produces:

    Element Msg

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

    Element msg

```

In my mind, I expected `searchView`'s values of type `Msg` to be able to be “assigned” to `msg`. I believe that this is the root cause of my misunderstanding.

I don’t have a real idea about what should change in that error message to make it clearer. Re-reading it after banging my head on this for the past hour, it looks obvious now. At the time, it didn’t.

Thanks for your time and have a great day!  
François

```auto
$ elm --version
0.19.1

```

---

<div class="post-metadata">

**Author:** ![digital-ember](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/digital-ember/32/2998_2.png) [@digital-ember](https://discourse.elm-lang.org/u/digital-ember)\
**Post date:** [April 2, 2020, 5:49am UTC](https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415/2 "2020-04-02T05:49:21Z")

</div>

Well, as you probably know by now, `Msg` is the name of a specific, custom type, whereas `msg` is a unbound type variable (I think that’s what it’s called).  
The confusion might stem from the “convention” of these two having the same name, with only the casing of the first letter being different.  
I remember that I tripped over the same problem several times. Even though I think the convention of having a `Model` and a `Msg` type in Elm makes sense once you see through the Matrix, it can be confusing if the semantics of these types isn’t fully understood yet.

What I actually did (and still do sometimes) in my code is not necessarily using just `Msg` and `Model`, especially if I reuse existing code (rename refactoring ftw).  
Instead, I try to come up with names that are more meaningful _to me_, to have richer semantics associated with the names. As for unbound type variables, like the lower-case `msg` in your case, I used a prefix at the beginning, e.g. `ubMessage`.

This might help the eye to see the kind of discrepancy you had described in your example, at least I profited.

As for the error message: would it have helped you if the compiler would have “said”, additionally:

`Msg` is a custom type, whereas `msg` is an unbound type variable. Maybe you want the type signature to actually read `Msg`?

I can see how Evan already contemplated to add something like that, but decided against it for a good reason I’m not aware of.

---

<div class="post-metadata">

**Author:** ![francois](https://avatars.discourse-cdn.com/v4/letter/f/77aa72/32.png) [@francois](https://discourse.elm-lang.org/u/francois)\
**Post date:** [April 2, 2020, 9:04pm UTC](https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415/3 "2020-04-02T21:04:25Z")

</div>

No, I’m fine with the existing convention.

```auto
searchView : Model -> Element msg

```

I expected the above to be the same as if I was “assigning” `Msg` to `msg`, that’s all. Elm did point to the right place. I think it means I don’t know as much about types as I thought I did 🙂

Cheers!

---

<div class="post-metadata">

**Author:** ![lydell](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lydell/32/178_2.png) [@lydell](https://discourse.elm-lang.org/u/lydell)\
**Post date:** [April 3, 2020, 6:20am UTC](https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415/4 "2020-04-03T06:20:22Z")

</div>

This is how interpret the error message:

“In the type annotation, you’ve said that this function can produce _any_ type of message.

But in the function body, I see that this function only ever will produce messages of a type called `Msg`!

This means either:

- That you have a misleading type annotation. It says _any_ message, but only produces `Msg` messages. If so, change the type annotation to `Msg` instead of `msg`!
- That you’ve accidentally used a specific message in this function, but you intended it to be generic. If so, replace `SearchFor` with something of a generic type!  
”

---

<div class="post-metadata">

**Author:** ![francois](https://avatars.discourse-cdn.com/v4/letter/f/77aa72/32.png) [@francois](https://discourse.elm-lang.org/u/francois)\
**Post date:** [April 3, 2020, 12:54pm UTC](https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415/5 "2020-04-03T12:54:21Z")

</div>

Wow lydell, this is a great message. Maybe some form of it can be added to core? Thanks a bunch everyone, and have a nice day!

---

<div class="post-metadata">

**Author:** ![evancz](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/evancz/32/16_2.png) [@evancz](https://discourse.elm-lang.org/u/evancz)\
**Post date:** [April 3, 2020, 5:24pm UTC](https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415/6 "2020-04-03T17:24:02Z")

</div>

Thank you for reporting this! I 100% think the message you got isn’t good enough. Def should be a **Hint** or **Note** for that case!

Can @francois or @lydell put an [SSCCE](http://sscce.org/) of this in [`elm/error-message-catalag`](https://github.com/elm/error-message-catalog/issues)?

I periodically go through the issues there to improve error messages, and I’d love to improve this particular message in a future release! I know a lot of people get tripped up on `msg` vs `Msg` early on, but it had not occurred to me to address it this way.

---

<div class="post-metadata">

**Author:** ![francois](https://avatars.discourse-cdn.com/v4/letter/f/77aa72/32.png) [@francois](https://discourse.elm-lang.org/u/francois)\
**Post date:** [April 5, 2020, 4:52pm UTC](https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415/7 "2020-04-05T16:52:15Z")

</div>

Done Evan: [https://github.com/elm/error-message-catalog/issues/332](https://github.com/elm/error-message-catalog/issues/332)

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [April 15, 2020, 4:52pm UTC](https://discourse.elm-lang.org/t/beginner-thought-process-on-type-mismatch-error/5415/8 "2020-04-15T16:52:15Z")

</div>

Closed on April 15, 2020, 4:52pm UTC

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
