Pull to refresh
17
0
Илья Симоненко @xkorpsex

Пользователь

Send message
Да дело не в том есть или нет мебель, она то как-раз там есть. Дело в том, что там нет физически места для кровати и дивана одновременно, по этому там нет кровати.
Я не понимаю как можно жить в Лайнере. Я работал в том районе около года и там крайне неуютно находиться без машины. По сути весь район — поле, исполосованное шоссе, на котором натыканы многоэтажки на довольно большом расстоянии друг от друга. При этом единственный вариант парковки там — это подземная, что недешево.
Второй момент — 50т.р. за студию в которой нет даже кровати? Зачем так жить?

Кстати прямо сейчас список доступных апартаментов не работает.
Я, кстати, увидел, где вы работаете, и начинаю понимать ваш поинт. Не очень понял зачем только заходить с раздачи минусов, если из ссылки выше он вообще не следует. Но спасибо хоть за такое объяснение)
Окей,
Начнем с того, что не вместо, в Scala есть как declaration-site variance: class Foo[+A], так и use-site variance: def someMethod[T <: Bar](foo: T)

Рассматриваемая проблема в том, что при вызове метода def test[A <: Gen[T], T](a: A), T без явного указания инферится в Nothing. Это чистый declaration-site, который есть и в Java — замените <: на extends.

Вопрос: причем здесь вообще use-site?
Кажется variance это не совсем связанная с сабжем вещь
Ну не только пересказ, здесь есть вещи, про которые в доках не сказано, например о важности порядка неявных параметров мне в интернете инфы найти вообще не удалось.
А тайпклассы это отдельная тема, о которой даже на хабре уже много статей, я даже ссылку в тексте оставил.
Ну если бы класс Parser был прост и интуитивен, я бы не написал об этом целую статью :)

На самом деле ответ на ваш вопрос есть в самой статье — не нужно любую задачу решать через монады.

Есть проблема в том, что скала достаточно богатый язык, чтобы в нем было очень легко прострелить себе ногу, но можно научиться брать эту его сторону под контроль и писать понятно.

В целом, в функциональном программировании есть свои паттерны (можно сказать что монада — один из них), и, научившись их распознавать, читать код становится намного проще. Тут похожая ситуация на ту, которая происходит, когда впервые изучаешь и пытаешься применять рекурсии. Как только мозг выворачивается в нужную сторону, все становится намного понятнее.
Да, это моя ошибка — я в процессе экспериментов избавился от PartialFunctions, но тут забыл заменить. Теперь исправил, на обычную функцию.

Спасибо за замечание)
Хм, тогда соглашусь.

Но тут тоже можно выкрутиться монадическим парсером, если сначала токенизировать в мапу по именам полей с помощью Parser[Map[String, String], String], а потом использовать мапу как остаток и парсить в сущность Parser[T, Map[String, String]]

Опять же, не знаю стал ли бы я так делать в продакшне)
Я согласен с вашими тезисами.

1. Придется, пришлось бы в любом случае, пока у нас парсер не обладает своим разумом.
2. Экранирования нет, и я написал почему. Акцент статьи на понимании того, куда можно вкрутить монаду, при желании. Не хотелось нагружать примеры логикой, к этому не относящейся.
3. Parser-combinators — тоже самое, статья не именно о том как парсить CSV.

Еще есть вариант разбивать строку по полям с помощью OpenCSV и потом работать не со строкой на входе, а со списком строк, тогда код из статьи будет применим с минимальными корректировками, но изобретать эскейпинг не придется.
Не понял мысль? Какой такой порядок?

Имплиситы это более удобный способ передачи параметров и не более. С помощью него можно сделать ручной DI, только чуть меньшим количеством знаков.

Следовательно, вы можете сделать так:
case class A(v: Int)

case class B(implicit a: A)

case class C(implicit b: B)


implicit val a = A(10)

implicit val b = B()

val c = C()


Но вот так уже не можете, так как получите ошибку компиляции:
implicit val b = B()

implicit val a = A(10)

val c = C()

поскольку в момент объявления b скоуп не содержит никакого имплиситного значения типа A.

И этим отличается ручной DI от автоматизированного — когда у вас пара классов — создавать их явно очень здравая идея, но если вы создаете в коде кучу компонент, следить за порядком их объявления и создания может стать утомительно.
Зачем для каждого? Можно для групп компонентов: Thin cake pattern. Или все зависимости объединить в один «контекст»

Здесь мысль в том, чтобы вместо большого кейка, делать небольшие модули, которые собирать вручную, и собирать кейк уже из них. Мысль в каком-то смысле здравая.

Я в общем и не выступаю против ручного DI через конструктор. Считаю что в случае микросервисной архитектуры например, использовать какую-то тулу это явный оверинжиниринг.
Смотрел на него, но видимо там тоже речь о макросах, да и про проблему циклических зависимостей ничего не написано. Мне было интересно просто попробовать другой взгляд.
Трейты — видимо речь о cake-паттерне?
Cake-паттерн заставляет плодить слишком много лишних сущностей (трейтов) для каждого компонента, у меня был опыт его использования в одном средних размеров проекте, удовольствия он приносит мало.
Имплиситы — сами по себе не делают DI, поскольку остается важным порядок их объявления.
Reader-monad — это можно сказать родственная идея. Но там тоже нужно учитывать порядок инжекта (поправьте кстати меня, если я недопонял концепцию), есть проблемы с множественными зависимостями. Ну и в целом, скорее всего для них захочется притянуть scalaz, который далеко не всем по душе.

А вообще конечно же можно и без них, особенно если у вас небольшие проекты.
А в java-мире до сих пор средствами языка выкрутиться было нельзя (а теперь, с default-реализациями теперь тоже можно делать cake), по этому все просто берут библиотеку, использующую reflection — то есть guice или spring — и не парятся.

Information

Rating
Does not participate
Registered
Activity