我需要为我的模型编写大量类型安全的 getter 和 setter(这是一个记录)。getter 非常简洁,我对此很满意。
getFoo = .foo
Run Code Online (Sandbox Code Playgroud)
这非常适合用作内联函数,而无需为其指定名称:
Maybe.map .foo maybeModel
Run Code Online (Sandbox Code Playgroud)
.仅比最低要求的代码(字段名称)多一个字符 ( )。无法获得更多的无样板文件。
但是编写等效设置器的最短方法是什么?现在我做
Maybe.map2 (\x v -> {x | foo = v} ) maybeModel maybeValue
Run Code Online (Sandbox Code Playgroud)
现在这不再是“毫无意义的”,并且有很多样板文件foo,其中大多数是难以输入的特殊字符。
为了澄清起见,有一个相关线程介绍如何摆脱为每个字段编写单独的 getter 的情况。我对此很满意,但我只是希望手指和眼睛更轻松。
没有等效的.foo语法速记方式,而且它会一次又一次地出现。
如果您想了解有关 Evan 省略此类内容的推理的更多信息(例如,关于制作类似 setter 语法或!foo其他特殊符号的建议),邮件列表上有很多关于该主题的长时间讨论。与 Elm 的许多设计决策一样,我认为答案可以归结为保持单一的做事方式并让新手轻松上手。
我发现解决笨拙的 setter 语法的最简洁方法是为表单的每个值创建一个 setter:
setFoo : Foo -> Model -> Model
setFoo foo model = { model | foo = foo }
Run Code Online (Sandbox Code Playgroud)
由于该model值位于最后,因此可以通过管道轻松组合:
updateModel : Foo -> Bar -> Model -> Model
updateModel foo bar model =
model
|> setFoo foo
|> setBar bar
Run Code Online (Sandbox Code Playgroud)
或者如果你想更简洁一点,你可以使用>>缩短上面的内容:
updateModel2 : Foo -> Bar -> Model -> Model
updateModel2 foo bar = setFoo foo >> setBar bar
Run Code Online (Sandbox Code Playgroud)
您的Maybe.map2示例可以这样写,其中maybeModel和maybeValue与您的示例进行交换:
Maybe.map2 setFoo maybeValue maybeModel
Run Code Online (Sandbox Code Playgroud)
当然,您必须创建大量样板 setter 代码,但在我看来,它比语言提供的 setter 语法使用起来更自然,而且看起来更好。