# Buttons labelled with the number of times they have been clicked

I am new to functional programming and I decided to learn it thru Elm instead of haskell. I wrote a practice code where there are 2 buttons and their names correspond to the number of times they are clicked. The following is my implementation:

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)

main = Html.beginnerProgram {model=model, view=view, update=update}

-- model
type alias Model =
{ a : Int
, b : Int
, total : Int}

model : Model
model = Model 0 0 0

-- view
type Msg = Add Foo
type Foo = A | B

view : Model -> Html Msg
view model =
div []
[ button [onClick (Add A)] [text (toString model.a)]
, button [onClick (Add B)] [text (toString model.b)]
, div [] [ text (toString model.total)]
]

-- update
update : Msg -> Model -> Model
update msg model =
case msg of
case foo of
A ->
let
a = model.a + 1
total = a + model.b
in
{model | a = a, total = total}
B ->
let
b = model.b + 1
total = b + model.a
in
{model | b = b, total = total}


I feel like that the above code is a dumb implementation of what I wanted to accomplish. Can somebody suggest a better implementation?

## migrated from stackoverflow.comNov 21 '17 at 18:26

This question came from our site for professional and enthusiast programmers.

• I recommend you configure your editor to format-on-save using elm-format – user633183 Nov 21 '17 at 16:22
• Thank you. I just learned how to do that. BTW, any idea why elm-format uses 4-spaces indentation? It's a bit too much for me. I think 2 spaces are enough. – jocab Nov 22 '17 at 10:12

Here are a few things I'd recommend changing:

1. There's no need to store the sum of a and b. You can always compute it in the view with a + b. This simplifies the update function a lot.

2. You can match Foo A and Foo B in update instead of a nested case.

3. Optionally, you can destructure model into {a, b} in view. I don't have any opinion on this. Either way is fine.

Here's the final elm-format'd code:

module Main exposing (..)

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)

main =
Html.beginnerProgram { model = model, view = view, update = update }

type alias Model =
{ a : Int
, b : Int
}

model : Model
model =
Model 0 0

type Msg

type Foo
= A
| B

view : Model -> Html Msg
view { a, b } =
div []
[ button [ onClick (Add A) ] [ text (toString a) ]
, button [ onClick (Add B) ] [ text (toString b) ]
, div [] [ text (toString (a + b)) ]
]

update : Msg -> Model -> Model
update msg model =
case msg of

• There's one more change I'd personally make: use <| to reduce parentheses: text (toString a) -> text <| toString a and similar for the two lines below. – Dogbert Nov 22 '17 at 4:17