等效于 setter 以匹配 Elm 记录类型的 `.foo` getter

Equivalent setter to match the `.foo` getter for an Elm record type

我需要为我的模型写很多类型安全的getter和setter(这是一个记录)。 getter 非常简洁,我对此很满意。

getFoo = .foo

这非常适合用作内联函数而无需为其命名:

Maybe.map .foo maybeModel

仅比最低要求代码(字段名称)多一个字符 (.)。无法再获得无样板文件。

但是写等价物的最短方法是什么setter?现在我做

Maybe.map2 (\x v -> {x | foo = v} ) maybeModel maybeValue

现在不再是 "pointless",foo 周围有很多样板,其中大部分是难以输入的特殊字符。

为了澄清,有一个 关于如何摆脱必须为每个字段编写单独的 getter。我对此很好,但我只是希望它对手指和眼睛更容易。

.foo 语法没有等效的简写形式,它是一次又一次出现的东西。

如果您想了解更多关于 Evan 省略此类内容的原因(例如,使 setter 语法像 !foo 或其他特殊符号)。与 Elm 的许多设计决策一样,我认为答案归结为保持单一的做事方式并让新手轻松使用。


解决我发现的笨拙 setter 语法的最简洁方法是为表单的每个值创建一个 setter:

setFoo : Foo -> Model -> Model
setFoo foo model = { model | foo = foo }

由于 model 值排在最后,因此可以通过管道轻松组合:

updateModel : Foo -> Bar -> Model -> Model
updateModel foo bar model =
    model
        |> setFoo foo
        |> setBar bar

或者如果你想更简洁一点,可以用>>来缩短上面的内容:

updateModel2 : Foo -> Bar -> Model -> Model
updateModel2 foo bar = setFoo foo >> setBar bar

您的 Maybe.map2 示例可以这样写,其中 maybeModelmaybeValue 与您的示例互换:

Maybe.map2 setFoo maybeValue maybeModel

当然,您必须创建大量样板 setter 代码,但在我看来,使用起来感觉更自然,而且看起来比语言提供的 setter 语法好得多。