How is Stream-cons # :: translated to Scala?

I am currently studying Scala, working through the book "Scala Programming." So far, there has been a good explanation of everything that looks weird (from the perspective of a Java programmer), but this one example of using Stream to generate a Fibonacci sequence leaves me puzzled:

def fibFrom(a: Int, b: Int): Stream[Int] = a #:: fibFrom(b, a + b) 

How is the Stream built? Of course, the #:: operator is somehow responsible for this. I understand that since it ends with : it is right-associative, but that does not explain the creation of Stream. I assume that this is implicitly translated to the constructor, but I don’t understand why and how.

I already searched for the answers in Predef.scala and LowPriorityImplicits.scala , but so far no luck.

Can someone enlighten me?

+6
source share
2 answers

It is the correct associative, so it works as a method with the correct argument:

 fibFrom(b, a + b).#::(a) 

At least that's what he is trying to do syntactically. Stream[Int] has no such method. Fortunately, object Stream has an implicit some ConsWrapper class that has this method ( code ).

So what do you get after implicit permission:

 immutable.this.Stream.consWrapper(fibFrom(b, a + b)).#::(a) 
+8
source

A stream is like a list. He knows only his head and the rest of the stream: Stream (head: T, tail: stream [T]). The difference is that the thread is evaluated lazily. ':' At the end of the method name, says that the method is the correct associative. Thus, the expression a # :: fibFrom (b, a + b) is translated (by the compiler) into fibFrom (b, a + b). #: :( a).

+2
source

Source: https://habr.com/ru/post/914890/


All Articles