Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you manage an explosion of update paths/Msg constructors?

Tags:

elm

I've finished the Elm guide and noticed on very simple examples, the update function grows to 3 cases and the Msg type can have 3 constructors. I imagine on an intermediate project, this would grow to 20 and on an advance project, it might be hundreds. How do you manage this? I foresee this being a source of version control contention if every developer needs to add a new constructor for their feature.

I worked on a react-redux project and it has a concept of combining reducers to solve this problem. I did not run across that concept in Elm. Does it have one?

like image 412
Daniel Kaplan Avatar asked May 30 '17 20:05

Daniel Kaplan


2 Answers

You can define msg type consists of child/sub msg types, and of course, updater can be combined with sub functions. ie.

-- Counter


type CounterMsg
    = Increment
    | Decrement


type alias CounterModel =
    Int


updateCounter : CounterMsg -> CounterModel -> ( CounterModel, Cmd msg )
updateCounter msg model =
    case msg of
        Increment ->
            ( model + 1, Cmd.none )

        Decrement ->
            ( model - 1, Cmd.none )



-- Todo


type TodoMsg
    = AddTodo String


type alias TodoModel =
    List String


updateTodo : TodoMsg -> TodoModel -> ( TodoModel, Cmd msg )
updateTodo msg model =
    case msg of
        AddTodo str ->
            ( str :: model, Cmd.none )



-- unified


type alias Model =
    { counter : CounterModel
    , todos : TodoModel
    }


type Msg
    = Counter CounterMsg
    | Todo TodoMsg


initModel =
    { counter = 0, todos = [] }


update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
    case Debug.log "message" msg of
        Counter countermsg ->
            let
                ( newmodel, cmd ) =
                    updateCounter countermsg model.counter
            in
                ( { model | counter = newmodel }, cmd )

        -- etc...
        _ ->
            ( model, Cmd.none )
like image 113
Tosh Avatar answered Nov 15 '22 11:11

Tosh


Take a look at Richard's implementation for RealWorld/Conduit. It provides a realistic way to structure a large enough app (few thousands lines of code).

In short, on complex projects there is the idea of a Page that can have its own model and update and view.

Within each page you could have a large Msg but that is not really an issue. 20 tags is actually quite manageable. 50 is also manageable as discovered by NoRedInk programmers in their production code.

like image 28
pdamoc Avatar answered Nov 15 '22 09:11

pdamoc