Подтвердить что ты не робот

Поиск документации Scala для #::

Я пытаюсь найти документацию для метода оператора Scala #::. Я считаю, что он определен в классе Stream из-за пример, который я нашел, который использует его.

Мой вопрос не относится к этому методу (хотя я хотел бы знать, где находятся документы), но как искать документы Scala в целом. Я попытался ввести #:: в поле поиска в левом верхнем углу страницы документации (2.8.1), но ничего не нашел.

4b9b3361

Ответ 1

Я предлагаю использовать Справочный указатель - он разработан специально для поиска любого символа (класс, черты, методы, vals, vars ) независимо от его иерархической позиции - в отличие от индекса левой руки Scaladoc, который не показывает внутренние классы, черты или объекты.

К сожалению, он доступен только в ночное время. Вы можете увидеть все это в ночной Scaladoc. Обратите внимание на верхний квадрат в левом фрейме над индексом.

Надеюсь, что он будет связан с Scala 2.9.0.

Изменить. Начиная с 2.9.0, ссылочный индекс начал связываться с Scaladoc. Не нужно теперь обращаться к ночным документам.

Ответ 2

Как уже упоминалось, #:: определяется на scala.collection.immutable.Stream.ConsWrapper. Я просто хотел немного подумать, почему это так.

В общем случае для вызова оператора на объект этот объект должен существовать. Однако идея с потоком - это хвост потока, который не оценивается до тех пор, пока это не будет. Итак, рассмотрим следующий поток:

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

Обычно нам нужно оценить рекурсивный вызов fibs, чтобы мы могли называть его #::. Это приведет к безудержной рекурсии. Это НЕ то, что мы хотим. Мы хотим, чтобы получатель был по-имени Stream. Следовательно, ConsWrapper:

Конструктор для ConsWrapper - это class ConsWrapper[T](tail: => Stream[T]), берущий по имени Stream, и он создается через неявное преобразование Stream.consWrapper[T](stream: => Stream[T]), которое также принимает по имени Stream.

Следовательно, мы выполнили неявное преобразование результата функции, которая еще не была вызвана, и мы наметили эффект вызова #:: с помощью ссылки this по имени.

Ответ 3

Проблема заключается в том, что скалярный поиск не позволяет вам искать внутренний класс/объект (т.е. чей родитель не является пакетом). Объявление #:: равно либо Stream.#::, либо Stream.ConsWrapper.#:::

object Stream { 
  //STUFF
  /** An extractor that allows to pattern match streams with `#::`.
   */
  object #:: {
    def unapply[A](xs: Stream[A]): Option[(A, Stream[A])] = 
      if (xs.isEmpty) None
      else Some((xs.head, xs.tail))
  }
  class ConsWrapper[A](tl: => Stream[A]) {
    def #::(hd: A): Stream[A] = new Stream.Cons(hd, tl)
    def #:::(prefix: Stream[A]): Stream[A] = prefix append tl
  }
  //MORE STUFF
}

Вы можете запросить это как RFE для инструмента scaladoc в trac.

В плагине IntelliJ IDEA scala вы могли бы использовать поиск символов (CTRL + ALT + SHIFT + N) и набрали #::, и это было бы немедленно отобразили обе декларации #::.

Ответ 4

Хорошо, обычно, если мы видим

foo bar baz 

тогда bar - это метод, определенный для foo, поэтому мы сначала рассмотрим определение класса/объекта foo, затем дерево наследования/дерева признаков вверх (+ в неявных преобразованиях и из foo в текущем файле и в (напрямую) включены файлы).

За исключением "bar" заканчивается двоеточие, что здесь и происходит. Затем его следует читать в обратном порядке -

foo bar: baz 

не

foo.bar: (baz)

но

baz.bar: (foo) 

Итак, мы должны искать способ, описанный выше, но не для foo, а для baz.

Ответ 5

Этот конкретный метод определен в вложенном классе внутри Stream, называемом scala.collection.immutable.Stream.ConsWrapper.

И нет, я понятия не имею, как можно найти его. Я случайно наткнулся на него. И хотя я знал, где его найти сейчас, когда я хотел опубликовать ссылку на класс здесь, в моем ответе, я все еще не мог найти его в первой (и даже второй и третьей) попытке.