我可以指定类型是任意记录吗?

发布于 2025-01-14 20:40:54 字数 653 浏览 0 评论 0原文

我有一个类型

type alias WithStatus l =
  { l
  | status :
    Status
  }

This 使用状态字段扩展记录。

现在我想创建一个函数,它接受一条记录并赋予它特定的状态,所以我做了:

addStatus : Status -> l -> WithStatus l
addStatus status l =
  { l
  | status =
    status
  }

然而 elm 抱怨 l 可能不是一条记录。

This is not a record, so it has no fields to update!

21|>  { l
22|   | status =
23|     status
24|   }

This `l` value is a:

    l

But I need a record!

这是真的。然而,elm 也无法知道类型别名中的 l 是一条记录,它会在使用站点上进行检查。所以它在这里抱怨似乎有点奇怪。

有没有办法表达一个函数,它接受任何记录 l并添加状态?

I have a type

type alias WithStatus l =
  { l
  | status :
    Status
  }

This extends a record with a status field.

Now I'd like to make a function that takes a record and gives it a particular status, so I made:

addStatus : Status -> l -> WithStatus l
addStatus status l =
  { l
  | status =
    status
  }

However elm complains that l could potentially not be a record.

This is not a record, so it has no fields to update!

21|>  { l
22|   | status =
23|     status
24|   }

This `l` value is a:

    l

But I need a record!

Which is true. However elm has no way of knowing that the l in the type alias is a record either, it checks for that on the use site. So it seems a little odd that it's complaining here.

Is there a way to express a function which takes any record l and adds a status?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不打扰别人 2025-01-21 20:40:54

有没有办法表达一个函数,它接受任何记录 l 并添加状态?

您可以

setStatus : Status -> WithStatus l -> WithStatus l
setStatus status l =
  { l | status = status }

替换现有状态,但以您希望的方式引入新字段的能力不再可能了。

它曾经是,从 0.7 到 0.16(2015 年发布),它被删除了,因为 < a href="https://elm-lang.org/news/compilers-as-assistants" rel="nofollow noreferrer">感觉实际上并非如此有用的:

简化记录

这里有一个很长的故事。简而言之,记录更新现在使用普通的等号,如下所示:

<前><代码> { 点 | x = 4 }

而不是像以前那样使用向后箭头<-。这是很多人都被绊倒的事情,即使在他们之后有很多经验,所以总的来说,我认为这会让事情变得更友好一些。当在一个案例中使用时,向后箭头也会导致奇怪的代码纹理,这样你就可以到处都有向前和向后箭头。

好吧,但是如果您热衷于语言设计,那么长话短说会很有趣!

Elm 使用非常酷的记录系统。它基于 Daan Leijen 的一篇优秀论文,可让您添加和删除记录中的字段,同时保持类型简单。我真的很喜欢这种力量与简单的结合!

我在 0.7 中添加了对此的支持,当时,我从未见过一种语言(具有真正工作的编译器)允许像这样的字段添加和删除。所以我有直觉,但没有办法获得真正的经验。我担心它可能会鼓励过于复杂的代码,所以从一开始我就非常保守,知道随着我们获得更多数据,我们可以扩展或收缩功能。

嗯,已经两年多了,结果已经出来了。几乎没有人使用过字段添加或删除。在人们确实使用它的少数情况下,它很快就变得非常疯狂。我所知道的一个真实案例记录在此处 如果你想看看,代码可以用自定义类型重写,无论如何结果都更好。


去掉添加和删除也会让Elm更容易优化(更多描述这里)。如果我们的目标平台不是 JavaScript,但也允许在 JS 中进行一些简化,则尤其如此。事实上,我们针对 0.16 运行的基准测试表明,这使得记录更新速度更快!< /p>

Is there a way to express a function which takes any record l and adds a status?

You can do

setStatus : Status -> WithStatus l -> WithStatus l
setStatus status l =
  { l | status = status }

which replaces an existing status, but the ability to introduce new fields in the way you were hoping isn't possible any more.

It used to be, from 0.7 until 0.16 (released in 2015) where it was removed because it wasn't felt to be actually all that useful:

Simplified Records

There is kind of a long story here. The short version is that record update uses a normal equals sign now, like this:

     { point | x = 4 }

Instead of using the backwards arrow <- like before. This was something that a lot of people got tripped up on, even after they had a lot of experience, so overall I think this will make things a bit friendlier. The backwards arrows also led to weird code texture when used within a case such that you have forwards and backwards arrows going everywhere.

Okay, but the long story is interesting if you are into language design!

Elm uses a very cool record system. It is based on an excellent paper by Daan Leijen that lets you add and remove fields from records, all while keeping the types simple. I really love this mix of power and simplicity!

I added support for this back in 0.7, and at the time, I had never seen a language (with a real working compiler) that allowed field addition and deletion like this. So I had intuition, but no way to get real experience. I worried that it could encourage overly complex code, so from the start I was very conservative, knowing that we could expand or contract the features as we got more data.

Well it has been more than two years since then, and the results are in. Pretty much no one ever used field addition or deletion. In the few cases where people did use it, it got pretty crazy pretty quickly. The one real-world case I know of is recorded here if you want to see, and the code could be rewritten with custom types, which turned out nicer anyway.

Removing addition and deletion will also make Elm easier to optimize (described more here). This is especially true if we are targeting platforms besides JavaScript, but allows some simplifications in JS too. In fact, the benchmarks we ran for 0.16 show that this made record updates a lot faster!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文