Обновить поле в записи Elm-lang с помощью функции точки?

Можно ли обновить поле в записи Elm с помощью функции (или каким-либо другим способом) без явного указания точного имени поля?

Пример:

> fields = { a = 1, b = 2, c = 3 }
> updateField fields newVal fieldToUpdate = { fields | fieldToUpdate <- newVal }
> updateField fields 5 .a -- does not work

ОБНОВИТЬ:

Чтобы добавить некоторый контекст, я пытаюсь высушить следующий код:

UpdatePhraseInput contents ->
  let currentInputFields = model.inputFields
  in { model | inputFields <- { currentInputFields | phrase <- contents }}

UpdatePointsInput contents ->
  let currentInputFields = model.inputFields
  in { model | inputFields <- { currentInputFields | points <- contents }}

Было бы очень хорошо, если бы я мог вызвать мифическую функцию updateInput следующим образом:

UpdatePhraseInput contents -> updateInput model contents .phrase
UpdatePointsInput contents -> updateInput model contents .points

person seanomlor    schedule 02.08.2015    source источник


Ответы (2)


Роллинг собственной функции обновления

Да, хотя, возможно, не так хорошо, как получение из поля. Но идея та же, вы пишете функцию, которая просто использует синтаксис обновления записи:

setPhrase r v = { r | phrase <- v }
setPoints r v = { r | points <- v }
updInputFields r f = { r | inputFields <- f r.inputFields }

Затем вы можете написать:

UpdatePhraseInput contents -> updInputFields model (flip setPhrase contents)
UpdatePointsInput contents -> updInputFields model (flip setPoints contents)

Focus библиотека

Когда вы объединяете field и fieldSet, вы получаете что-то вроде Focus. Хотя эта библиотека работает не только с записями. Вот пример того, как это будет выглядеть при использовании Focus:

phrase = Focus.create .phrase (\upd r -> { r | phrase <- upd r.phrase })
points = Focus.create .points (\upd r -> { r | points <- upd r.points })
inputFields = Focus.create .inputFields (\upd r -> { r | inputFields <- upd r.inputFields})

Затем вы можете написать:

UpdatePhraseInput contents -> Focus.set (inputFields => phrase) contents model
UpdatePointsInput contents -> Focus.set (inputFields => points) contents model
person Apanatshka    schedule 02.08.2015

В идеале вы могли бы определить функцию, которая могла бы выбрать, какое поле будет обновлено, но вы не можете.

См. эту статью, что объясняет, почему в настоящее время невозможно функционально обновить поля в записи в elm:

«Опытные функциональные программисты наверняка заметили, что многие из этих концепций очень похожи на линзы, а в Elm на самом деле уже есть библиотека, похожая на линзы, созданная самим Эваном, под названием Focus. Однако на самом деле это не решает проблему: она требует ручное описание сеттеров, как это делает чисто функциональный подход».

...и следующий комментарий от создателя из Elm, объясняя, почему предложенная поддержка этого не была добавлена ​​в недавней изменения в записи:

«Я обдумал это и отказался от этого. Я знаю это предложение. Это предложение по языковым функциям, а не простой синтаксис».

person thewoolleyman    schedule 24.08.2016