Реализация Ленивого Перечислителя в Кристалле - PullRequest
0 голосов
/ 10 января 2019

В Ruby для создания собственного ленивого перечислителя можно использовать Enumerator следующим образом:

enum = Enumerator.new do |e|
  e << value = ".a"
  loop { e << value = value.next }
end

enum.next # => ".a"
enum.next # => ".b"
enum.next # => ".c"
enum.rewind
enum.next # => ".a"

Какой идиоматический способ кристалла подражать такой вещи?

1 Ответ

0 голосов
/ 11 января 2019

Немного словеснее ... Посмотрите на Iterator<T>

class DotChar
  include Iterator(String)

  @current : String = ""

  def initialize
    @start = ".a"
    rewind
  end

  def next
    @current.tap { @current = @current.succ }
  end

  def rewind
    @current = @start
  end
end

e = DotChar.new
p e.next # => ".a"
p e.next # => ".b"
p e.next # => ".c"
e.rewind
p e.next # => ".a"

(Невозможно использовать enum в качестве идентификатора, так как это ключевое слово в Crystal.)

Вы можете сделать это намного проще, если пожертвуете перемоткой:

s = ".a"
e = Iterator.of { s.tap { s = s.succ } }

Возможно, в будущем появится способ сделать точно так же, как в Ruby, но эта работа еще не завершена (я надеюсь, что она еще не заброшена, похоже, она застопорилась полгода назад). См. эту проблему и этот запрос на получение для получения дополнительной информации.

...