简体   繁体   English

使用Elixir语言具有递归功能的流

[英]Stream with recursive function in Elixir language

In scala the code below works (I know it's weird, but I want to test stream concat with recursive functions) 在scala中,下面的代码有效(我知道这很奇怪,但是我想用递归函数测试流concat)

def ones(s: Stream[Int]): Stream[Int] = 1 #:: ones(s)
ones(Stream.from(1)).take(10).toList

I wrote some elixir code that should be equivalent to the scala code and it hangs. 我写了一些应该等同于scala代码的elixir代码,它挂了。 How can I get the same effect as the above scala code? 如何获得与上述scala代码相同的效果?

defmodule Ones do
  def ones(s) do
    head = Stream.take(s, 1)
    Stream.concat(head, ones(s))
  end
end

Ones.ones(Stream.iterate(1, &(&1 + 1))) |> Enum.take(10) # hang

It seems the #:: operator in scala evaluates its right argument lazily. 似乎scala中的#::运算符会延迟评估其正确的参数。 That's why you can construct "infinite" recursions like that and it still works out. 这就是为什么您可以像这样构造“无限”的递归,并且仍然可行。 In Elixir there is no notion of lazily evaluated arguments, so ones(s) always calls ones(s) at the end resulting in an infinite loop. 在Elixir中,没有延迟计算的参数的概念,因此ones(s)总是在最后调用ones(s) ,从而导致无限循环。 In order to avoid that you'd need to use a Stream function that explicitly deals with lazy values to construct your result, for example Stream.resource . 为了避免这种情况,您需要使用显式处理惰性值的Stream函数来构造结果,例如Stream.resource

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM