Elm中更新函数的类型错误

Type error in the update function in Elm

我是 elm (0.17) 的新手,我试图了解它是如何工作的。在这种情况下,我尝试开发一种项目估算。 这就是我所做的:

import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (..)

import Html.Events exposing (onClick)

main =
  Html.program
    { init = init
    , view = view
    , update = update
    , subscriptions = subscriptions
    }

-- model
type alias Host = {
  name : String,
  cost : Int
}
type alias Model =
  { email : String
  , hosting : List Host
  , period : List Int
  , interventionDays : List Int
  , total : Int
  }

init : (Model, Cmd Msg)
init =
  (Model "init@email.fr" [{name="AAA", cost=15}, {name="BBB", cost=56}, {name="CCC", cost=172}] [1..12] [1..31] 0, Cmd.none)


type Msg = Submit | Reset

calculate : Int
calculate = 42 -- to test

update : Msg -> Model -> (Model, Cmd Msg)
update action model =
  case action of
    Submit ->
      (model, calculate)
    Reset ->
      (model, Cmd.none)

-- SUBSCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
  Sub.none


-- view
hostOption host =
  option [ value (toString host.cost) ] [ text host.name ]

durationOption duration =
  option [value (toString duration) ] [ text (toString duration)]

view : Model -> Html Msg
view model =
  Html.form []
    [ h2 [] [ text "Estimate your project"]
    , input [ placeholder model.email ] []
    , select []
      (List.map hostOption model.hosting)
    , select []
      (List.map durationOption model.period)
    , select []
      (List.map durationOption model.interventionDays)
    , Html.span [][text (toString model.total)]
    , button [onClick Submit] [text "Submit"]
    , button [onClick Reset] [text "Reset"]
    ]

我想我已经理解了 elm 背后的一些想法,但我需要帮助,因为 elm-make 命令 returns:

The 1st and 2nd branches of this `case` produce different types of values.

40|   case action of
41|     Submit ->
42|       (model, calculate)
43|     Reset ->
44|>      (model, Cmd.none)

The 1st branch has this type:

    ( a, Int )

But the 2nd is:

    ( a, Cmd a )

Hint: All branches in a `case` must have the same type. So no matter which one
we take, we always get back the same type of value.

Detected errors in 1 module.                                        

我明白这个问题,但我不知道如何解决。我是否必须定义我的计算函数才能处理模型数据?

谢谢

我猜您想将模型的 total 字段更新为 calculate

update 函数 returns 的第一个元组项是更新后的模型。按照目前的情况,您的两个操作 return 现有模型都没有改变它。所以你可以试试这个:

case action of
  Submit ->
    ({ model | total = calculate }, Cmd.none)
  Reset ->
   init

有关更新记录的语法,请参阅 here

注意我也把Reset分支改成了returninit,初始模型和命令

编译器错误告诉您更新方法在某些情况下会 return 一个 (Model, Cmd) 元组,而在另一些情况下会 return 一个 (Model, Int) 元组.

您拥有的更新功能应该 return 修改后的模型以及执行操作的 Cmd,换句话说,一个 (Model, Cmd) 元组。

如果你 return (model, calculate) 它将 return 一个 (Model, Int) 元组,因为 calculate 是一个 Int。这就是破坏编译的原因。

所以要修复它,首先您需要决定如何处理每个消息。我根据它们的名称假设 Calculate Msg 将更新总数,而 Reset Msg 会将模型设置为默认状态。

为此你可以这样做:

    case action of
       Submit ->
          ({ model | total = calculate }, Cmd.none)
       Reset ->
          init

在这种情况下,两个分支都将 return 类型为 (Model, Cmd) 的元组。

请注意 Reset 分支将 return init,它已经是 (Model, Cmd).

类型

查看官方指南以获取更多示例:http://guide.elm-lang.org/index.html