Elm 0.19可能是默认值

时间:2019-02-03 13:57:44

标签: string int elm maybe

我已经阅读了文档,但是我仍然不明白如何在代码中使用Maybe.withDefault。因为从String.toInt获得Maybe Int,所以我不能使用+号添加尝试转换为Integers的值。这是榆木0.19。我该如何解决?

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" ]
    ]

4 个答案:

答案 0 :(得分:2)

withDefault : a -> Maybe a -> a

此函数收到2个参数(最后一个是返回值)。

如果aInt,则我们有:

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

第一个参数第二个参数Nothing后将返回的参数。

因此,如果第二参数不是Nothing,则该函数将返回第二参数内的值。

一个简单的例子:

-- hard-code 2nd param
withDefault 10 (Just 20) -- this function call results 20
withDefault 10 Nothing -- this function call results 10

高级的:

-- 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

输入您的代码:

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) }

如您所见,Maybe.withDefault确保您在Int计算中始终收到add returned Int

没有它,您将始终收到Maybe Int,而Maybe Int的添加将始终返回Maybe Int

注意: 我上面的代码仅用于Maybe.withDefault用法说明,不适用于生产代码

答案 1 :(得分:1)

您确实需要一个带有text的字符串,但是您的onClicks可以处理带有Ints的消息。即

button [ onClick (AddNum 7)] [ text "7" ]

我建议您也更改模型以使其与ints一起使用,这样就完全不需要从字符串到字符串的任何转换

答案 2 :(得分:1)

关于您的问题:

  1. String.fromInt返回Maybe Int,这意味着该值可以是Just IntNothing
  2. 您不能仅添加例如Just 1Nothing在一起,甚至Just 1Just 2
  3. 您需要以某种方式从Just 1中提取数字或指定默认值(如果是Nothing(例如0)。
  4. 这是Maybe.withDefault派上用场的地方。它可以从任何Int中提取Maybe Int(与NothingJust无关)。它包含2个参数:

    • first是第二个参数为Nothing
    • 时使用的默认值。
    • 秒是实际的Maybe

因此在您的代码中,您可以像这样使用它:

{model 
  | curNum = 
      String.fromInt <|
        (Maybe.withDefault 0 <| String.toInt model.curNum) 
        + (Maybe.withDefault 0 <| String.toInt model.mainNum)
}

说了这么多,您只需在模型中使用Int,在视图中使用String.fromInt,就可以避免所有麻烦。

答案 3 :(得分:0)

我通过创建一个将Maybe Int-> Int转换的函数来解决了该错误:

checkInt : Maybe Int -> Int
checkInt x = case x of
    Just y -> y
    Nothing -> 0