Reputation: 176
I have read the documentation, but i still don't understand how to Maybe.withDefault in my code. Because from a String.toInt I get Maybe Int, I cant use a + sign to add the values I try to convert into Integers. This is Elm 0.19. How can I fix this?
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
main =
Browser.sandbox { init = init, update = update, view = view }
-- MODEL
type alias Model = {mainNum : String, curNum : String}
init : Model
init =
{
mainNum = ""
,curNum = ""
}
-- UPDATE
type Msg = AddNum String | Add | Clear
update : Msg -> Model -> Model
update msg model =
case msg of
AddNum number ->
{model | curNum = model.curNum ++ number}
Add ->
{model | curNum = String.fromInt ((String.toInt model.curNum) +
(String.toInt model.mainNum))}
Clear ->
init
-- VIEW
view : Model -> Html Msg
view model =
div []
[ div [] [ text model.curNum]
, button [ onClick (AddNum "1" )] [ text "1" ]
, button [ onClick (AddNum "2" )] [ text "2" ]
, button [ onClick (AddNum "3" )] [ text "3" ]
, div [] []
, button [ onClick (AddNum "4" )] [ text "4" ]
, button [ onClick (AddNum "5" )] [ text "5" ]
, button [ onClick (AddNum "6" )] [ text "6" ]
, div [] []
, button [ onClick (AddNum "7" )] [ text "7" ]
, button [ onClick (AddNum "8" )] [ text "8" ]
, button [ onClick (AddNum "9" )] [ text "9" ]
, div [] []
, button [ onClick (AddNum "0" )] [ text "0" ]
, button [ onClick Clear] [ text "Clear" ]
]
Upvotes: 1
Views: 2092
Reputation: 2955
Regarding your question:
String.fromInt
returns Maybe Int
, it means that the value can be either Just Int
or Nothing
Just 1
and Nothing
together or even Just 1
and Just 2
Just 1
somehow or specify default value if it's Nothing
(e.g. 0).This is where Maybe.withDefault
comes in handy. It can extract Int
from any Maybe Int
(doesn't matter if it's Nothing
or Just
). It takes 2 parameters:
Nothing
Maybe
valueSo in your code you can use it like this:
{model
| curNum =
String.fromInt <|
(Maybe.withDefault 0 <| String.toInt model.curNum)
+ (Maybe.withDefault 0 <| String.toInt model.mainNum)
}
Having said all this you could just save all the trouble by using Int
s in your model and String.fromInt
in your views.
Upvotes: 2
Reputation: 2932
withDefault : a -> Maybe a -> a
This is a function received 2 params (the last one is the returned value).
If a
is an Int
then we have:
withDefault : Int -> Maybe Int -> Int
-- if `a` is a `Float` then we have
withDefault : Float -> Maybe Float -> Float
-- in general, if `a` is an `X` then we have
withDefault : X -> Maybe X -> X
The 1st param is the one that will be returned once the 2nd param is Nothing
.
So if the 2nd param isn't Nothing
then the function will return the value inside 2nd param.
so basic example:
-- hard-code 2nd param
withDefault 10 (Just 20) -- this function call results 20
withDefault 10 Nothing -- this function call results 10
advanced ones:
-- 2nd param is Nothing
withDefault 10 (String.toInt "abc") -- this function call results 10
-- 2nd param is not Nothing
withDefault 10 (String.toInt "123") -- this function call results 123
into your code:
Add ->
let
cur : Int
cur =
Maybe.withDefault 0 (String.toInt model.curNum)
main : Int
main =
Maybe.withDefault 0 (String.toInt model.mainNum)
in
{ model | curNum = String.fromInt (cur + main) }
As you can see, the Maybe.withDefault
makes sure you always receive Int
for your add returned Int
calculation.
Without it, you will always receive Maybe Int
and the add of Maybe Int
will always returns Maybe Int
.
Note:
My code above is only for Maybe.withDefault
usage explanation, not for production code
Upvotes: 4
Reputation: 176
I have fixed the error by creating a function that converts Maybe Int -> Int:
checkInt : Maybe Int -> Int
checkInt x = case x of
Just y -> y
Nothing -> 0
Upvotes: 0
Reputation: 21007
You do need a string with text
but your onClicks can work with messages that take Ints. i.e.
button [ onClick (AddNum 7)] [ text "7" ]
I suggest you change your model to work with ints too, and then you won't have to do any conversion from/to strings at all
Upvotes: 1