Какой предпочитаемый способ реализации "доходности" в Scala?

Я пишу код для докторской диссертации и начинаю использовать Scala. Мне часто приходится заниматься обработкой текстов. Я привык к Python, чье утверждение 'yield' чрезвычайно полезно для реализации сложных итераторов над большими, часто нерегулярно структурированными текстовыми файлами. Схожие конструкции существуют и в других языках (например, C#), не зря.

Да, я знаю, что были и предыдущие потоки по этому поводу. Но они выглядят как взломанные (или, по крайней мере, плохо объясненные) решения, которые явно не работают хорошо и часто имеют непонятные ограничения. Хотелось бы написать что-то вроде этого:

import generator._

def yield_values(file:String) = {
  generate {
    for (x <- Source.fromFile(file).getLines()) {
      # Scala is already using the 'yield' keyword.
      give("something")
      for (field <- ":".r.split(x)) {
        if (field contains "/") {
          for (subfield <- "/".r.split(field)) { give(subfield) }
        } else {
          // Scala has no 'continue'.  IMO that should be considered
          // a bug in Scala.
          // Preferred: if (field.startsWith("#")) continue
          // Actual: Need to indent all following code
          if (!field.startsWith("#")) {
            val some_calculation = { ... do some more stuff here ... }
            if (some_calculation && field.startsWith("r")) {
              give("r")
              give(field.slice(1))
            } else {
              // Typically there will be a good deal more code here to handle different cases
              give(field)
            }
          }
        }
      }
    }
  }
}

Хотелось бы посмотреть код, реализующий функции generate() и give(). BTW give() должна быть названа yield(), но Scala уже взяла это ключевое слово.

Я понял, что по непонятным мне причинам продолжения Scala могут не работать внутри оператора for. Если да, то функция generate() должна поставлять эквивалентную функцию, которая работает как можно ближе к оператору for, так как код итератора с yield почти неизбежно сидит внутри цикла for.

Пожалуйста, я бы предпочел не получать ни одного из следующих ответов:

  1. 'yield' - отстой, продолжения лучше. (Да, в общем, с продолжениями можно сделать больше. Но их трудно понять, и 99% времени итератор - это все, что вам нужно или нужно. Если Scala предоставляет много мощных инструментов, но их слишком сложно использовать на практике, язык не будет успешным.)
  2. Это дубликат. (См. мои комментарии выше.)
  3. Вам следует переписать код, используя потоки, продолжения, рекурсии и т.д. (См. #1. Я также добавлю, что технически вам тоже не нужны циклы. Если уж на то пошло, то технически вы можете делать абсолютно все, что вам нужно, используя SKI-комбинаторы.)
  4. Ваша функция слишком длинная. Разбейте ее на более мелкие кусочки и вам не понадобится "урожайность". В любом случае, вам придется сделать это в производственном коде. (Во-первых, "доходность" в любом случае сомнительна. Во-вторых, это не код производства. В-третьих, при такой обработке текста, очень часто, разбивая функцию на мелкие кусочки - особенно когда язык заставляет делать это, потому что в нем отсутствуют полезные конструкции - только усложняет понимание кода .)
  5. Перепишите свой код с переданной функцией. (Технически, да, это можно сделать. Но в результате получается уже не итератор, а цепочечные итераторы намного приятнее цепочечных функций. В общем, язык не должен заставлять меня писать в неестественном стиле - конечно, создатели Scala в это верят, так как они дают говно синтаксического сахара.)
  6. Перепишите свой код этим, этим, или другим способом, или каким-то другим крутым, потрясающим способом, о котором я только что подумал.

20
задан ROMANIA_engineer 8 September 2017 в 13:43
поделиться