I'm learning elm and I'm trying to use types to better describe my domain. But I got stuck here: I can't use number literals as types/type aliases? Is there an "elmish way" to do this?
module Main exposing (main)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
type alias Model =
{ pos : Int }
type Up = 1
type Down = -1
type Direction = Up | Down
type Msg
= Go Direction
initialModel : Model
initialModel =
{ pos = 0 }
update : Msg -> Model -> Model
update msg model =
case msg of
Go Up ->
{ model | pos = model.pos + Up }
Go Down ->
{ model | pos = model.pos + Down }
view : Model -> Html Msg
view model =
div []
[ button [ onClick Go Up ] [ text "+1" ]
, div [] [ text <| String.fromInt model.count ]
, button [ onClick Go Down ] [ text "-1" ]
]
main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, view = view
, update = update
}
(ellie link: https://ellie-app.com/7HRDRKHRCFDa1 )
In order to use Up
and Down
with operator +
, they would have to be values, not types – values of the same type as the other operand. So define them as constants of type Int
instead:
up : Int
up = 1
down : Int
down = -1
Then you can write your update
function as:
update : Msg -> Model -> Model
update msg model =
case msg of
Go Up ->
{ model | pos = model.pos + up }
Go Down ->
{ model | pos = model.pos + down }
For the full working code, see this Ellie.
The only other change I made was to your buttons' onClick
– it needs to be onClick <| Go Up
to tell the compiler that Up
is an argument to Go
, and the result is an argument to onClick
.