简化记录的递归更新

Simplifying recursive updating of records

这段代码可以简化吗?

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 不接受内部记录更新。

我想你要找的是 focus library:

Focus

A Focus is a way to work with particular parts of a large chunk of data. On the most basic level, it lets you get and set fields of a record in a simple and composable way. This means you could avoid writing special record update syntax and use something that composes much more elegantly.

It gives you the ability to write stuff like freeze in the following snippet:

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