简化记录的递归更新

时间:2015-05-17 08:17:19

标签: elm

这段代码可以简化吗?

update : Action -> Model -> Model
update action model =
  let
    formValue = model.formValue
  in
    case action of
      UpdateWhat what ->
        let
          newValue = { formValue | what <- what }
        in
          { model | formValue <- newValue }
      UpdateTrigger trigger ->
        let
          newValue = { formValue | trigger <- trigger }
        in
          { model | formValue <- newValue }

由于我计划添加更多Update...个子句,因此将其抽象出来是有帮助的。

代码按原样编写,因为Elm不接受内部记录更新。

1 个答案:

答案 0 :(得分:2)

我认为您正在寻找的是focus library

  

焦点

     

Focus是一种处理大块数据特定部分的方法。在最基本的层面上,它允许您以简单且可组合的方式获取和设置记录的字段。这意味着您可以避免编写特殊记录更新语法并使用更优雅的组合。

     

它使您能够在以下代码段中编写冻结等内容:

mario =
    { super = False
    , fire  = False
    , physics = { position = { x=3, y=4 }
                , velocity = { x=1, y=1 }
                }
    }

freeze object =
    set (physics => velocity) { x=0, y=0 } object

在代码示例中,物理和速度是焦点。您可以使用以下代码创建焦点,以使用您的示例:

formValue = Focus.create .formValue (\f r -> { r | formValue <- f r.formValue })
what      = Focus.create .what      (\f r -> { r | what      <- f r.what })
trigger   = Focus.create .trigger   (\f r -> { r | trigger   <- f r.trigger })

update : Action -> Model -> Model
update action model =
  case action of
    UpdateWhat w -> Focus.set (formValue => what) w model
    UpdateTrigger t -> Focus.set (formValue => trigger) t model