Эквивалентный сеттер, соответствующий геттеру .foo для типа записи Elm.

Мне нужно написать много геттеров и сеттеров для моей модели (это рекорд). Геттеры очень лаконичны, и я доволен этим.

getFoo = .foo

Это идеально подходит для использования в качестве встроенной функции без указания имени:

Maybe.map .foo maybeModel

Только один дополнительный символ (.) сверх минимально необходимого кода (имя поля). Не могу получить больше без шаблонов.

Но как кратчайшим образом написать эквивалентный сеттер? Теперь я делаю

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

Теперь это больше не «бессмысленно», и вокруг foo много шаблонов, большинство из которых трудно набирать специальные символы.

Для пояснения, есть связанный поток о том, как избавиться от необходимости писать отдельный геттер для каждого поля. Я в порядке с этим, но я просто хочу, чтобы это было легче для пальцев и глаз.


person Thilo    schedule 05.10.2018    source источник


Ответы (1)


Не существует эквивалентного сокращения синтаксиса .foo, и это то, что появляется снова и снова.

В списке рассылки ведутся долгие дискуссии на эту тему, если вы хотите узнать больше о причинах, по которым Эван опускает такую ​​вещь (например, предложения по созданию синтаксиса установки, такого как !foo или другие специальные символы). Как и многие дизайнерские решения Elm, я думаю, что ответ сводится к сохранению единого способа выполнения чего-либо и упрощению его для новичков.


Самый лаконичный способ обойти неуклюжий синтаксис сеттера, который я нашел, — это создать один сеттер для каждого значения формы:

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 можно было бы написать так, где maybeModel и maybeValue поменялись местами из вашего примера:

Maybe.map2 setFoo maybeValue maybeModel

Конечно, вам придется создать много шаблонного кода сеттера, но, на мой взгляд, работать с ним намного естественнее, и он выглядит намного лучше, чем синтаксис сеттера, предоставляемый языком.

person Chad Gilbert    schedule 05.10.2018
comment
Тем не менее, переключение параметров, позволяющее комбинировать эти сеттеры, является изящным. - person Thilo; 05.10.2018
comment
Не существует эквивалентного сокращения синтаксиса .foo, и это то, что появляется снова и снова. В списке рассылки ведутся долгие дискуссии на эту тему, если вы хотите узнать больше о причинах, по которым Эван опускает такую ​​вещь (например, предложения по созданию синтаксиса установки, такого как !foo или другие специальные символы). Как и многие дизайнерские решения Elm, я думаю, что ответ сводится к сохранению единого способа выполнения чего-либо и упрощению его для новичков. - person Chad Gilbert; 05.10.2018