レンズを使用してコレクション内の要素を更新する最良の方法は何ですか? 例えば:
case class Ingredient(name: String, quantity: Int)
case class Recipe(val ingredients: List[Ingredient])
レンズを使用して、1 つの材料の量を変更した新しいレシピを作成したい場合、どのように行うのが最適ですか?
私が試したアプローチは、オンザフライでレンズを作成することです: Lens[List[Ingredient], Ingredient]
. ただし、これは少しぎこちなく感じます。
case class Recipe(val ingredients: List[Ingredient]) {
import Recipe._
def changeIngredientQuantity(ingredientName: String, newQuantity: Int) = {
val lens = ingredientsLens >=> ingredientLens(ingredientName) >=> Ingredient.quantityLens
lens.set(this, newQuantity)
}
}
object Recipe {
val ingredientsLens = Lens.lensu[Recipe, List[Ingredient]](
(r, i) => r.copy(ingredients = i),
r => r.ingredients
)
def ingredientLens(name: String) = Lens.lensu[List[Ingredient], Ingredient](
(is, i) => is.map (x => if (x.name == name) i else x),
is => is.find(i => i.name == name).get
)
}
case class Ingredient(name: String, quantity: Int)
object Ingredient {
val quantityLens = Lens.lensu[Ingredient, Int](
(i, q) => i.copy(quantity = q),
i => i.quantity
)
}