Изменение атрибута с помощью объективов-моноклей с использованием значения другого атрибута

у меня следующая модель

import monocle.macros.Lenses
import monocle.function.all._
import monocle.std.list._

@Lenses("_") case class Poll(pollChoices: List[PollChoice], totalVoteCount: Int)
@Lenses("_") case class PollChoice(id: Int, value: Int, percentage: Int)

Чего я пытаюсь добиться, так это обновить атрибут pollChoices опроса, обновив все процентные атрибуты каждого элемента в списке pollChoices. Моя проблема в том, что новые процентные значения основаны на атрибуте value в PollChoice и totalValueCount в Poll.

Что я сделал до сих пор:

val poll = Poll(List(PollChoice(1,3,0), PollChoice(2,5,0)), 8)

(Poll._pollChoices composeTraversal each composeLens PollChoice._percentage)
  .modify(oldPercentage => oldPercentage + 1)(poll)

Но таким образом я могу получить доступ только к атрибуту percentage элемента, который я обновляю на этапе изменения, мне также нужно значение.

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


person Daniel B.    schedule 13.12.2016    source источник


Ответы (1)


Не думаю, что это можно выразить в одном объективе, но отдельный объектив внутри .modify работает хорошо:

Poll._pollChoices.composeTraversal(each).modify { choice =>
  PollChoice._percentage.set(choice.value / poll.totalVoteCount)(choice)
}(poll)
person lunaryorn    schedule 16.12.2016
comment
Спасибо, это нормально для моего случая использования! - person Daniel B.; 16.12.2016