Difficulty understanding Type Mismatch error for beginner
Over on Beginner thought process on type mismatch error, I described how I had difficulty understanding a Type Mismatch error:
-- 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
lydell explained the message thusly:
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!
The self-contained example is:
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
-- MAIN
main =
Browser.sandbox { init = init, update = update, view = view }
-- MODEL
type alias Model =
{ name : String
}
init : Model
init =
Model ""
-- UPDATE
type Msg
= Name String
update : Msg -> Model -> Model
update msg model =
case msg of
Name name ->
{ model | name = name }
-- VIEW
-- ****************
-- Change msg to Msg and the compilation error goes away
-- ****************
view : Model -> Html msg
view model =
div []
[ viewInput "text" "Name" model.name Name
]
viewInput : String -> String -> String -> (String -> msg) -> Html msg
viewInput t p v toMsg =
input [ type_ t, placeholder p, value v, onInput toMsg ] []
I ran into this yesterday working with a co-worker who's new to Elm. Another couple aspects of this error that make it hard for beginners to troubleshoot are:
- What's the difference between Capital & lowercase "msg" ...
- How do I get
Msgif I havemsgaka: where to apply atoMsg : Msg -> msgfunction usually in someviewcode... - Which direction do I go? EG: is it
msg -> MsgorMsg -> msgand WHY.
In our case the idea was to rip some code from another part of the app, stitch it into a different context and make the minimal amount of changes to have something rendering on the screen (regardless of whether or not the behavior was correct)...
The more nefarious issue is what I call Top-Down vs Bottom-Up in Elm.... where
- Top-Down would be "Type-driven api design" where you start by adding/modifying the types and let the implementations follow.
- Bottom-Up would be starting by copy/paste/replacing some implementation and changing the types to fit.
Issue in Bottom-Up is specifically WHICH types to change... eg: do we change the type of the implementation so it fits in it's context (which may or may not be possible depending on parent-child relationships between Msg's) or do we change the types of the context to satisfy the more general type of the child.
The whole premise of "Parent Child" relationships between Sum types in Elm seems to be the root of a significant deal of confusion, even amongst experienced Elm devs.
I know other "UI" focused language design communities offer a number of other organizational primitives like Streaming api's ala: rxjs / SolidJS ... OR Monadic DSL's vs Applicative DSL's ala: https://github.com/janestreet/bonsai/blob/761d04847d5f947318b64c0a46dffa17ad413536/docs/blogs/why_no_bind.md
And there's other ideas in the wild I've stumbled on but who's implementations don't have NEARLY the community backing that the Elm architecture has built up over the years.
QUESTION: I wonder if there's either One: an answer to the "which direction do I need to fix the types in?" or I suppose more philosophically relevant, is there a better "Parent Child" model we can leverage for helping Beginners understand how to model programs?