更新Elm中记录内嵌套值的简便方法(0.18) [英] Concise way of updating a nested value inside a record in Elm (0.18)

查看:69
本文介绍了更新Elm中记录内嵌套值的简便方法(0.18)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种更新Elm中记录内嵌套值(0.18)的简洁方法。

I am looking for a concise way of updating a nested value inside a record in Elm (0.18).

给出以下示例:

person = { name = "Steven", address = { country = "Spain", city = "Barcelona" } }

我可以使用以下表达式将person.name更新为 Steve:

I can update person.name to "Steve" using the following expression:

{ person | name = "Steve" }

但是,我正在寻找一种更新嵌套值的方法。例如,我想将person.address.city更新为马德里。我尝试了以下操作:

However, I am looking for a way to update a nested value. For instance, I would like to update person.address.city to "Madrid". I tried the following:

{ person | address.city = "Madrid" } 
{ person | address = { address | city = "Madrid" } } 
{ person | address = { person.address | city = "Madrid" } } 

编译器拒绝所有这些变化。我看到的最短的有效选项是:

The compiler rejects all these variations. The shortest valid option I see is:

let personAddress = person.address in { person | address = { personAddress | city = "Madrid" } }

这似乎有点太多代码,只是为了更新嵌套值,您知道是否有更好/更短的方法来实现这一目标?

This seems to be a bit too much code just to update a nested value, Do you know if there is a better/shorter way of achieving that?

推荐答案

您上一个使用<$ c的示例$ c> let / / 语法在Elm 0.18中尽可能简洁,而无需求助于其他软件包。

Your last example with the let/in syntax is as concise as is possible in Elm 0.18 without resorting to additional packages.

话虽这么说,在功能语言中,您经常会发现Lenses的概念对于更新嵌套记录很有用。在 arturopala / elm-monocle 处有一个Elm包。提供构建和执行镜头的功能,以更简洁地获取和设置嵌套记录值。

That being said, in functional languages, you will often find the concept of Lenses useful for updating nested records. There is an Elm package at arturopala/elm-monocle which provide the ability to construct and execute lenses for more concisely getting and setting nested record values.

使用该程序包,您可以构建镜头来进行简洁的操作,例如

Using that package, you could build up lenses that would let you do concise things like this:

personWithUpdatedCity = personCity.set "Madrid" person

getCityOfPerson = personCity.get person

缺点是您必须自行编写所有镜头接线代码。在Haskell中,这种连接可以由编译器完成。在榆木中,我们没有那么奢侈。

The downside is that you have to write all the lens wiring code yourself. In Haskell, this wiring can be done by the compiler. In Elm, we don't have that luxury.

上述镜头所需的榆木代码为:

The Elm code needed for the above lenses would be this:

addressCityLens : Lens Address String
addressCityLens =
    Lens .city (\cn a -> { a | city = cn })

personAddressLens : Lens Person Address
personAddressLens =
    Lens .address (\a p -> { p | address = a })

personCity : Lens Person String
personCity =
    compose personAddressLens addressCityLens

As您会看到,这比设置嵌套值要繁琐而且代码更多。由于繁琐的工作,您可能暂时希望坚持使用 let / in 示例,除非您的代码

As you can see, it's tedious and much more code than you may expect to set a nested value. Due to that tedium, you may want to stick to the let/in example for the time being, unless your code uses nested sets all over the place.

有一个有关在Elm中简化设置值的话题的较早讨论,但这已经有一段时间没有生效了。

There is an older discussion on the topic of making setting value easier in Elm here, but it hasn't been active for some time.

这篇关于更新Elm中记录内嵌套值的简便方法(0.18)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆