Comments 10
Велосипедненько.
А что, если в CSV будут дополнительные поля (или поля будут не по порядку)? Придётся менять код?
Экранирования в строках, кажется, нет (но несложно добавить).
.toInt будет бросать исключение, если что не так. Не вижу, чтобы оно обрабатывалось.
Почему бы не использовать Scala Parsers (правда эта библиотека небыстрая)?
"Очевидный подход" как-то нагляднее и наверняка быстрее.
1. Придется, пришлось бы в любом случае, пока у нас парсер не обладает своим разумом.
2. Экранирования нет, и я написал почему. Акцент статьи на понимании того, куда можно вкрутить монаду, при желании. Не хотелось нагружать примеры логикой, к этому не относящейся.
3. Parser-combinators — тоже самое, статья не именно о том как парсить CSV.
Еще есть вариант разбивать строку по полям с помощью OpenCSV и потом работать не со строкой на входе, а со списком строк, тогда код из статьи будет применим с минимальными корректировками, но изобретать эскейпинг не придется.
Придется, пришлось бы в любом случае, пока у нас парсер не обладает своим разумом.
Это не так сложно. Я просто добавлял первой строкой в CSV-подобном формате названия полей, и потом с помощью таблицы "имя->индекс столбца" искал нужные столбцы, из которых брал данные.
Но тут тоже можно выкрутиться монадическим парсером, если сначала токенизировать в мапу по именам полей с помощью Parser[Map[String, String], String], а потом использовать мапу как остаток и парсить в сущность Parser[T, Map[String, String]]
Опять же, не знаю стал ли бы я так делать в продакшне)
Parser {case src =>
" в листинг, это магическое слово, превращающее лямбду в частично примененную функцию. А то у меня мозг взорвался, прежде чем я понял код. Спасибо за замечание)
Так вот почему у меня мозг взрывается от этого кода. Все дело в недостающем case
!
Если серьезно, то у меня вопрос:
Я вот знаком со Скалой преимущественно по статьям на Хабре :). И для меня конструкции типа определения Parser
в статье — вынос мозга каждый раз.
А вы правда привыкли к ней настолько, чтобы легко и непринужденно оперировать подобными сущностями?
Или все еще требуется значительное усилие, чтобы разобраться, что к чему?
Написать-то один раз можно (даже я, наверное, справлюсь — с n-ной попытки). Но потом же кто-то этот код регулярно читает.
Меня действительно этот вопрос интересует.
На самом деле ответ на ваш вопрос есть в самой статье — не нужно любую задачу решать через монады.
Есть проблема в том, что скала достаточно богатый язык, чтобы в нем было очень легко прострелить себе ногу, но можно научиться брать эту его сторону под контроль и писать понятно.
В целом, в функциональном программировании есть свои паттерны (можно сказать что монада — один из них), и, научившись их распознавать, читать код становится намного проще. Тут похожая ситуация на ту, которая происходит, когда впервые изучаешь и пытаешься применять рекурсии. Как только мозг выворачивается в нужную сторону, все становится намного понятнее.
Писать на scala можно по-разному.
У меня процентов 90 scala-кода вообще императивно написано, только с добавлением функциональных .map(), .foreach() и т.п. Тяжёлую функциональщину приходится писать очень редко, да и в конце концов такой код воспринимается как несложный dsl (например, Scala Parsers).
Но от применения серьёзной функциональщины чаще отказываюсь из-за тормознутости (и временами дикой прожорливости) результата, а не из-за сложности написания/понимания.
Пишем свои монады на Scala на примере CSV-парсера