Scala:#:::和+&#x2B之间的区别与拉齐主义者

发布于 2025-01-25 03:56:20 字数 1754 浏览 2 评论 0原文

我希望#:::和++在两个操作数都是Lazylist时的行为相同。实际上,随着以下代码键入VS代码 /金属工作表:

LazyList.from(0) ++ LazyList.from(0)
LazyList.from(0) #::: LazyList.from(0)

两者都评估lazylist [int] = lazylist(&lt;未计算&gt;)< / code>。完全有道理。如果我这样做:

def countFrom(initial: LazyList[Int]): LazyList[Int] =
    LazyList(initial.head) #::: countFrom(LazyList(initial.head + 1))

val m1 = countFrom(LazyList(0))

VS代码显示M1评估:lazylist [int] = lazylist(&lt;未计算&gt;),这对我来说又是完全有意义的。没有人要求任何元素,所以什么都不应计算。但是,如果我按以下内容更改#::: to ++:

def countFrom(initial: LazyList[Int]): LazyList[Int] =
    LazyList(initial.head) ++ countFrom(LazyList(initial.head + 1))

val m1 = countFrom(LazyList(0))

那么,VS代码在评估从调用count Count Count等的count等的同时,VS代码无法评估M1。这是一个我正在研究的项目的简化,它正在构建更有趣的lazylists

。 ,但它是由我(怪异的)从方法中暴露出来的。谁能解释这里发生了什么?

[在路易斯·米格尔·梅吉亚·苏阿雷斯(Luis MiguelMejíaSuárez)的评论之后]

感谢路易斯·米格尔·梅吉亚·苏阿雷斯(Luis MiguelMejíaSuárez如果我遇到了问题,可以随意修复我!)。在表达式x#::: y中为什么在Scala文档中命名为#::: :::的参数前缀)。由于#:::是在deferrer上定义的,因此这会导致y(lazylist)的隐式转换为deferrer ,将y包装到thunk(nullary函数)中。 x#::: y然后变成x lazyappendedall todeferrer(y)()()。然后,我想关键是lazyAppendedAll是通过名称的第二个参数,因此todeferrer(y)()()在需要之前实际上无法实际评估。现在,至于++,我在lazylist源中没有看到++的定义,因此我想它已继承并且具有更简单的定义,其中使用x ++ y << /code>,xy是参数,y是按值传递的,因此评估进入++。由于ylazylist,因此未计算元素,但必须将y评估为lazylist本身,这就是无限递归产生的地方。

I would expect #::: and ++ to behave identically when both operands are LazyLists. Indeed, with the following code typed into a VS Code / Metals worksheet:

LazyList.from(0) ++ LazyList.from(0)
LazyList.from(0) #::: LazyList.from(0)

both evaluate to LazyList[Int] = LazyList(<not computed>). Makes perfect sense. And if I do this:

def countFrom(initial: LazyList[Int]): LazyList[Int] =
    LazyList(initial.head) #::: countFrom(LazyList(initial.head + 1))

val m1 = countFrom(LazyList(0))

VS Code shows that m1 evaluates to: LazyList[Int] = LazyList(<not computed>) which again makes perfect sense to me. No one asked for any elements, so nothing should be computed yet. But if I change the #::: to ++ as per the following:

def countFrom(initial: LazyList[Int]): LazyList[Int] =
    LazyList(initial.head) ++ countFrom(LazyList(initial.head + 1))

val m1 = countFrom(LazyList(0))

then VS Code cannot evaluate m1 due to a stack overflow error while evaluating countFrom calling countFrom calling countFrom, etc. (Btw, yes, this is bizarre, contrived code. It's a simplification of code from a project I was working on that was constructing more interesting LazyLists.)

So apparently there IS a difference between ++ and #::: which is not exposed when concatenating LazyLists generated via the built-in from method, but which IS exposed by my (weird) countFrom method. Can anyone explain what's going on here?

[added after Luis Miguel Mejía Suárez's comment]

Thanks to Luis Miguel Mejía Suárez, I think I get it now, so I'm going to try to explain the details after having looked at the LazyList source (feel free to fix me if I get something wrong!). In the expression X #::: Y, Y is this, and X is the argument (which is why the parameter to #::: is named prefix in the scala docs). Since #::: is defined on Deferrer, this causes an implicit conversion of Y (a LazyList) into a Deferrer, which wraps Y into a thunk (nullary function). X #::: Y then becomes X lazyAppendedAll toDeferrer(Y)(). Then, I guess the key is that the second parameter to lazyAppendedAll is pass-by-name, so toDeferrer(Y)() is not actually evaluated until it is needed. Now as for ++, I did not see a definition of ++ in the LazyList source, so I guess it gets inherited and has a much simpler definition where, with X ++ Y, X is this and Y is the argument and Y is passed by value, and is thus evaluated on entry to ++. Since Y is a LazyList, the elements are not calculated, but Y must be evaluated down to the LazyList itself, and that's where the infinite recursion results.

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文