Возвращаемая и итерируемая коллекция с использованием yield в scala

У меня есть класс DateTime и TimeSpan в Scala (предположим, что операторы ‹ и + работают как надо). Я пытаюсь определить функцию «диапазона», которая принимает время начала/остановки и временной интервал для пошагового выполнения. В C# я бы сделал это с выходом, и я думаю, что смогу сделать то же самое в Scala... за исключением того, что я получаю странную ошибку.

В строке «выход t» я получаю «Недопустимое начало оператора».

  def dateRange(from : DateTime, to : DateTime, step : TimeSpan) =
  {
      // not sure what the list'y way of doing this is
    var t = from

    while(t < to)
    {
      yield t; // error: illegal start of statement
      t = t + step
    }
  }

Глядя на этот код, мне интересно 2 вещи: 1) что я сделал не так? 2) написанный код очень императивен (использует var t и т. д.). Какой более функциональный способ сделать это в Scala достаточно быстро?

Спасибо!


person fbl    schedule 28.10.2011    source источник
comment
yield в Scala не имеет ничего общего с yield в C# (или Python). Более того, у Scala нет ему эквивалента — поищите множество вопросов о Scala, Python, yield и генераторах. И, конечно же, поищите вопросы о том, чем на самом деле занимается yield.   -  person Daniel C. Sobral    schedule 29.10.2011
comment
Я сделал, и я был сбит с толку. Ответ Дебильского сказал мне все, что мне нужно было знать.   -  person fbl    schedule 29.10.2011


Ответы (3)


Вот версия решения @Debilski с периодами времени joda:

import org.joda.time.{DateTime, Period}

def dateRange(from: DateTime, to: DateTime, step: Period): Iterator[DateTime] =
  Iterator.iterate(from)(_.plus(step)).takeWhile(!_.isAfter(to))
person Mr Speaker    schedule 05.03.2013

В Scala yield — это специальный оператор для циклов for.

Я не знаю С#, но, насколько я понимаю, проще всего использовать collection.immutable.NumericRange.Exclusive[DateTime] или collection.immutable.NumericRange.Inclusive[DateTime], в зависимости от того, является ли ваш интервал эксклюзивным или инклюзивным.

Чтобы это работало, вам нужно создать экземпляр Integral[DateTime], который определяет арифметику для типа DateTime.

person 0__    schedule 28.10.2011
comment
Ну, Integral как-то глупо реализовывать для DateTime, похоже. Другой подход с Iterator.iterate намного лучше. - person 0__; 28.10.2011

person    schedule
comment
Если бы я мог поставить вам +1000, я бы это сделал. Это потрясающе. - person fbl; 28.10.2011