0

Вот минимальный пример, я могу определить функцию, которая дает мое следующее целое черезПервого элемента Ленивого потока в Scala

def nextInteger(input: Int): Int = input+1 

то я могу определить ленивый поток целых чисел, как

lazy val integers: Stream[Int] = 1 #:: integers map(x=>nextInteger(x)) 

к моему удивлению, принимая первый элемент этого потока является 2, а не 1

scala> integers 
res21: Stream[Int] = Stream(2, ?) 

В этом простом примере Я могу достичь желаемого результата, используя 0 вместо 1 в определении целых чисел, но как можно вообще настроить поток таким образом, чтобы начальное значение не терялось? В моем случае я настраиваю итеративный алгоритм и хочу знать начальное значение.

EDIT: Кроме того, я никогда не понимал, выбор дизайна, что делает следующий синтаксис сбой:

scala> (integers take 10 toList) last 
res27: Int = 11 

scala> integers take 10 toList last 
<console>:24: error: not found: value last 
       integers take 10 toList last 
            ^

Я считаю, обертывание вещи в скобках громоздкими, есть сокращенная я не знаю?

+2

Причина, по которой люди используют скобки, заключается в том, чтобы избежать таких вещей ... '1 # :: integers map (x => nextInteger (x))' is фактически '(1 # :: integers) .map (x => nextInteger (х)) '. Причина в том, что '# ::' лево-ассоциативный. И стенографию, которую я могу посоветовать и рекомендовать для '(целые числа принимают 10 toList) last' является' integers.take (10) .toList.last' –

+1

Death Note - отличное шоу – naomik

ответ

4

Возможно, вы думаете, что 1 #:: integers map(x=>nextInteger(x)) разобран как 1 #:: (integers map(x=>nextInteger(x))), пока он фактически разобран как (1 #:: integers).map(x=>nextInteger(x)). Добавление скобок исправляет проблему:

val integers: Stream[Int] = 1 #:: (integers map nextInteger) 

(Обратите внимание, что поскольку nextInteger это просто функция, вам не нужно, чтобы сделать лямбда для него, и так как Stream уже лень, делая integers ленивым ненужно)


Что касается вашего редактирования, ознакомьтесь с this отличным ответом на вопрос. Короче: нет простого пути. Дело в том, что если вы уже не знаете арность функций, участвующих, имеющие что-то вроде того, что вы предлагаете работа была бы адом для следующего человека, читающего ваш код ... Например,

myList foo bar baz 

Может быть быть myList.foo.bar.baz в ну как myList.foo(bar).baz, и вы не знали бы, не проверив определения foo, bar и baz. Скала решает устранить эту двусмысленность - она ​​всегда последняя.

+0

А, отлично, спасибо. Вы также можете прокомментировать мое синтаксическое редактирование? – Lindon

+0

@ Lindon Конечно, я отредактирую свой ответ. – Alec