2016-05-23 5 views
0

In scala den Code unten funktioniert (ich weiß, es ist seltsam, aber ich will Strom Concat mit rekursiven Funktionen testen)-Stream mit rekursive Funktion in Elixir Sprache

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

ich etwas Elixier Code geschrieben hat, die gleichwertig sein sollte der Scala-Code und es hängt. Wie kann ich den gleichen Effekt wie oben beschrieben erreichen?

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 
+0

Sie haben keine Bedingung zur Verfügung gestellt, um die Rekursion zu stoppen, deshalb hängt es. Ich weiß nicht über Scala, aber es sieht so aus, als ob Sie nur 10 Elemente aus dem Stream nehmen, da Streams faul sind, so ist dies genug, um zu stoppen. Korrigieren Sie mich wenn falsch, ich bin nur ein Anfänger;) – nightire

+0

@nightire Oben scala Code ist genau das gleiche mit Elixier-Code, aber man ist Arbeit, andere nicht. Ich weiß nicht, warum zwei Sprachen ein anderes Verhalten haben. – blueiur

Antwort

1

Es scheint, die #:: Betreiber in scala gemächlich sein rechtes Argument auswertet. Deshalb können Sie "unendliche" Rekursionen wie diese konstruieren und es funktioniert immer noch. In Elixir gibt es keine Vorstellung von träge ausgewerteten Argumenten, daher ruft ones(s) am Ende immer ones(s) auf, was zu einer Endlosschleife führt. Um dies zu vermeiden, müssen Sie eine Stream-Funktion verwenden, die explizit mit Lazy-Werten arbeitet, um Ihr Ergebnis zu erstellen, zum Beispiel Stream.resource.

+0

Thx für Ihren Kommentar. Ich brauche es für make prime stream http://exercism.io/submissions/612742e25fc84703ba091138cbef18e9 – blueiur

+0

'Stream.resource' sollte dafür ausreichen –