Хорошо, я возьму это на себя:)
ones
- это легкая отправная точка.Эта функция возвращает Stream
, чье первое значение равно 1
, а остальные значения можно вычислить, вызвав саму функцию ones
.Таким образом, любой запрос на «остаток» значений one
всегда будет начинаться с 1
, до бесконечности.
Следующее, на что нужно обратить внимание, это функция take
:
function (howmany) {
if (this.empty()) {
return this;
}
if (howmany == 0) {
return new Stream;
}
var self = this;
return new Stream(this.head(), function () {
return self.tail().take(howmany - 1);
});
}
Так что сверху вниз, если Stream
пуст, то не имеет значения, сколько элементов было запрошено, так как этот запрос не может быть выполнен, поэтому Stream
возвращает свое (пустое) значение "я"..
Если мы не запрашивали никаких элементов, например, howmany == 0
, то возвращается пустое значение Stream
, которое само по себе не даст никаких элементов, если его спросить.
Наконец, самое интересное.Ссылка на текущий Stream
заблокирована в области действия функции и возвращается новый Stream
.Этот новый Stream
создается с той же головой, что и текущий Stream
, и хвост которого создается функцией, которая будет take
на один элемент меньше из исходного хвоста Stream
, чем запрашивающий абонент.Так как голова - это один предмет, а хвост может генерировать howmany-1
предметов, вызывающий получит новый Stream
с возможностью доставки запрошенного количества предметов.
naturalNumbers
немногоmore tricky.
Функция naturalNumbers
возвращает Stream
, у которого 1
в качестве головы, и внутреннюю функцию для генерации хвоста.
Внутренняя функция возвращает результатвызов метода add
в потоке ones
с результатом вызова функции naturalNumbers
.Таким образом, мы можем догадаться, что это предполагает «соединение» двух Stream
вместе каким-то образом.
Как выглядит add?Это функция, которой передается Stream
:
function (s) {
return this.zip(function (x, y) {
return x + y;
}, s);
}
Мы можем распознать часть 'add' как внутреннюю функцию - она добавляет два значения вместе, так что это имеет смысл.Но что делает zip
?zip
- это функция, которая принимает функцию и Stream
в качестве параметров.
function (f, s) {
if (this.empty()) {
return s;
}
if (s.empty()) {
return this;
}
var self = this;
return new Stream(f(s.head(), this.head()), function () {
return self.tail().zip(f, s.tail());
});
}
Так что в случае добавления переданная функция была функцией 'add' (x + y),и Stream
был naturalNumbers
Stream
.
Что zip
делает с этими значениями?Если Stream
сам по себе пуст, возвращается «other» Stream
.Я думаю, это потому, что добавление [] к [2,4,6,8, ...] имеет больше смысла быть [2,3,6,8, ...], чем что-либо еще.т. е. первый поток обрабатывается как бесконечно много 0
или ""
.
Если переданный Stream
пуст, то применяется то же правило, что и выше, только в обратном порядке.т.е. добавление [2,4,6,8, ...] к [].
Теперь самое интересное.После получения ссылки на себя возвращается новый Stream
.Этот Stream
состоит из значения заголовка, которое представляет собой функцию «add», применяемую к элементам заголовка каждого Stream
, и функцию, которая при необходимости применяет функцию «add» к хвосту каждого Stream
.
Так что в случае ones().add(naturalNumbers())
это приведет к Stream
, чья голова равна 2
, так как функция 'add' вызывается с 1
и 1
(элемент headоба ones
и naturalNumbers
оба 1
).Таким образом, если этот новый Stream
будет добавлен к ones
, то будет добавлен элемент ones
head (всегда 1
) к элементу head нового Stream
(теперь 2
),предоставление 3
.
Хвост этого нового Stream
- это механизм для предоставления дополнительных «добавлений», если требуется.
Так что у нас остается в основном способ описания операцийнаноситься на элементы головы и хвоста.Только когда мы просим определенное количество элементов, мы проходим через механизм для создания этих элементов.
Так что, если вы позвоните ones().take(9999999999999999999999999999999).print()
, то для функции print
потребуется много ресурсов. необходимо , чтобы иметь значение, прежде чем оно сможет его распечатать - это обязательно заставит этот механизм выдавать столько 1
с.Но ones().take(9999999999999999999999999999999)
сам по себе является просто описанием элемента головы 1
и процессом доставки остальных предметов, но только по запросу.
Но ... Я мог бы ошибиться, потому что мне уже поздно, и я только что прочитал статью;)