@scala_ru

Страница 950 из 1499
Pavel
22.09.2017
11:09:40
а если прилага многослойная и тебе нужно прокинуть реально с нижнего слоя ошибку до самого юзера

это же геммор полный

Aleksei
22.09.2017
11:10:18
а зачем тебе юзеру кидать ошибку о том что база недоступна, например?

Oleg
22.09.2017
11:11:40
а если прилага многослойная и тебе нужно прокинуть реально с нижнего слоя ошибку до самого юзера
Ну вот же блин, твоя монадка это сделает ничем не хуже Future, просто у неё будет два сорта ошибок - известный структурированный тип, и Throwable, который ждёт большой recover в конце с надеждой, что в нём перечислено всё, что нужно и тесты это подтверэдают

Google
Oleg
22.09.2017
11:12:22
Идея в том, чтобы важные вещи переместить из второго сорта в первый

Daniel
22.09.2017
11:12:27
а есть такой же но с паттернами гоф?

Pavel
22.09.2017
11:14:04
окей в целом я понял

допустим есть DBIO - вставляет в базу - если срабатывает констрейт - это скажем так первый сорт, должен быть в Either, нету доступа к базе - это такой редкий случай - можно оставить в recovery

Mikhail
22.09.2017
11:15:31
а если прилага многослойная и тебе нужно прокинуть реально с нижнего слоя ошибку до самого юзера
ну слюшай, мы ФП пишем или где? в хаскеле и других ФП как-то с этим справляются.

Pavel
22.09.2017
11:17:07
Mikhail
22.09.2017
11:17:16
sealed class Layer1Error SaneError1Layer1 SaneError2Layer1 ... SomeRandomUnexpectedShitLayer1

Pavel
22.09.2017
11:18:03
@odomontois так, давай еще раз абстрагируясь от своей монады и говоря языком DBIO/Future. Допустим из DBIO нужно прокинуть ошибку до самого юзера. Ошибка находится в Either - тут два вариант:

или мы все же кинем throw с крутой ошибкой и она быстро дойдет до самого верха

тогда смысла в either нету)

Daniel
22.09.2017
11:18:56
вообще есть смысл

потому что стектрейса далеко не всегда хватает и нужно доп инфой напихать

Google
Oleg
22.09.2017
11:19:15
Pavel
22.09.2017
11:19:27
не про скорость, а про количество кода

чтобы до верха доставить

Oleg
22.09.2017
11:19:39
В одном случае throw, в другом raise

Pavel
22.09.2017
11:21:02
окей, сча

получается в конце концов у нас должен быть обработчик для Future[Either[Error, A]] который хендлит рековери по фьюче и хендлит все подтипы Error, так?

Mikhail
22.09.2017
11:23:46
а если прилага многослойная и тебе нужно прокинуть реально с нижнего слоя ошибку до самого юзера
Вообще ты хочешь странного - чтоб в глубине бросался определённый эксепшн через все приложение пролетал и ловился наверху. Компилятор то не в курсе. Тот кто будет смотреть на обработчик вообще не вкурит откуда это прилетает. Это магия, а явное, пусть и многословное, лучше неявного.

Pavel
22.09.2017
11:23:48
тогда смысл только получается только в том чтобы отделить важные и не важные ошибки, а скорее ошибки бизнес логики от внешних ошибок

так так ведь делаешься в Future

у тебя есть чейн flatmap’ов

кто-то запаролся и у тебя оно пошло на верх до юзера

Aleksei
22.09.2017
12:26:23
ты еще макро кэш попроси посмотреть =)

Nick
22.09.2017
12:47:36
нифига себе, вы уже об этом второй день трете?)

Oleg
22.09.2017
12:49:52
кто-то запаролся и у тебя оно пошло на верх до юзера
в общем, ты вопрошаешь о различиях, за что ты платишь своей сложностью 1. код parseAppealForm[ F[_] : FunctorRaise[?, AppealFormError] :AppealStore](data: String) : F[AppealForm] убеждается в том, что ты вынужден как-то обработаь исключение в своём процессе а parseAppealForm(data: String, database: AppealDatabase) : Future[AppealForm] - нет 2. Первый код абстрагируется от асинхронности и конкретной реализации, а потому засовываем в обычные синхронные property-тесты и в другие проекты с твиттер фьючами, тасками всевозможными стримами, второй требует обёрток и адаптеров и асинхронных тестсьютов 3. Имея Future[A] в любом месте кода, ты не можешь определить обработал ли ты уже интересующий эксепшн, или нужно ещё раз написать рекавер, в случае ошибок в аннотации, ты всегда знаешь какой уровень фэйла ты можешь тащить в данном уровне 4. При масштабной архитектурке, тебе будет сложно найти все куски кода catch em all, чтобы быть уверенным, что твоя ошибка не словится в каком-то промежуточном слое и до конца дойдёт твой эксепшн. 5. Манатки ништяковые, эксепшоны - отстойные. Однако, это не значит, что нужно броситься переписывать всё. Можно для начала обеспечить возможность использования ерроров в типах и это самое сложное. Потом добавить еррор там, еррор сям и ты сам войдёшь во вкус

нифига себе, вы уже об этом второй день трете?)
Я вчера отказался тереть, а сегодня много времени в транспорте провёл

KrivdaTheTriewe
22.09.2017
12:59:15
в общем, ты вопрошаешь о различиях, за что ты платишь своей сложностью 1. код parseAppealForm[ F[_] : FunctorRaise[?, AppealFormError] :AppealStore](data: String) : F[AppealForm] убеждается в том, что ты вынужден как-то обработаь исключение в своём процессе а parseAppealForm(data: String, database: AppealDatabase) : Future[AppealForm] - нет 2. Первый код абстрагируется от асинхронности и конкретной реализации, а потому засовываем в обычные синхронные property-тесты и в другие проекты с твиттер фьючами, тасками всевозможными стримами, второй требует обёрток и адаптеров и асинхронных тестсьютов 3. Имея Future[A] в любом месте кода, ты не можешь определить обработал ли ты уже интересующий эксепшн, или нужно ещё раз написать рекавер, в случае ошибок в аннотации, ты всегда знаешь какой уровень фэйла ты можешь тащить в данном уровне 4. При масштабной архитектурке, тебе будет сложно найти все куски кода catch em all, чтобы быть уверенным, что твоя ошибка не словится в каком-то промежуточном слое и до конца дойдёт твой эксепшн. 5. Манатки ништяковые, эксепшоны - отстойные. Однако, это не значит, что нужно броситься переписывать всё. Можно для начала обеспечить возможность использования ерроров в типах и это самое сложное. Потом добавить еррор там, еррор сям и ты сам войдёшь во вкус
плюсую за пятый пункт

Pavel
22.09.2017
13:15:21
я гляну чуть позже

Google
Pavel
22.09.2017
13:15:28
спасибо

KrivdaTheTriewe
22.09.2017
13:17:32
https://docs.scala-lang.org/sips/opaque-types.html

Alexander
22.09.2017
13:20:43
https://docs.scala-lang.org/sips/opaque-types.html
В Дотти же Phantom types будут.

Oleg
22.09.2017
13:43:16
Фантом - это отдельная вселенная, а здесь нормальные ньютайпы наконец

Alexander
22.09.2017
13:47:38
Фантом - это отдельная вселенная, а здесь нормальные ньютайпы наконец
Я, честно сказать, не очень понимаю, нафиг нужны ньютайпы если можно в отдельном унивёрсе также работать.

Oleg
22.09.2017
13:47:58
отдельный юниверс - это отдельный юниверс, типы оттуда ничему не соответствуют, существуют в сознании компилятора

Alexander
22.09.2017
13:48:25
newtype Id = Long

Oleg
22.09.2017
13:48:44
а ньютайп один к одному сопоставлен с реальным типом, в рантайме представлен так же, как он

Поэтому он сам по себе реален

Oleg
22.09.2017
13:52:55
А разве нельзя Scala Universe -> My Universe?
Ну вот есть у тебя foo: Int => MyPhantom.Int и ты запускаешь foo(2), что ты ожидаешь?

фантомный тип - это идеальная кандидатура на роль тега, даже в ньютайпе в реализации Майлза или Михаила

Но сам по себе он не может иметь рантайм репрезентации

инстанс MyPhantom.Int - это нонсенс

Alexander
22.09.2017
13:56:03
Ну вот есть у тебя foo: Int => MyPhantom.Int и ты запускаешь foo(2), что ты ожидаешь?
Ну я как раз и ожидал тегнутый инт, ага. А newtype и теги сильно различаются? У меня что-то руки не дошли почитать.

Oleg
22.09.2017
13:56:58
Ну я как раз и ожидал тегнутый инт, ага. А newtype и теги сильно различаются? У меня что-то руки не дошли почитать.
есть метод реализации ньютайпа через тего-подобные конструкции, грубо говоря, это кривая имплементация этого SIPа

Alexander
22.09.2017
13:58:10
Просто для меня Phantom types выглядят как более общий концепт, что ли.

Oleg
22.09.2017
13:58:13
Если говорить о тегах и ньютайпах в шейплез и супертаггед, то общая характеристика для них, если я правильно помню и Михаил сделал так же - A @@ Tag <:< A а для ньютайпа уже нет

Google
Oleg
22.09.2017
13:58:21
Для реализации ньютайпа ты можешь тегать и реальными классами, как вот сейчас в скале.

Т.е. никакой особо новой семантики фантомы не добавляют. Просто компилятор их раньше стирает и обращается попроще

KrivdaTheTriewe
22.09.2017
14:05:42
интересно, эта штука поможет той библиотеке , которая пытается добавить теорию размерности в скалу добавить?

Oleg
22.09.2017
14:25:23
Все типы, которые существуют просто для того, чтобы концы сошлись, хорошо засовываются в фантомы

Однако та реализация фантомов, что предложил Мартин, не предполагает расширение. Т.е. один раз разработчик библиотеки засовывает свой набор фантомов в свой обжект и с этим и живёшь. Вот это может и помешать

Vladimir
22.09.2017
15:33:28
а может у кого-то есть под рукой поделие на шейплезе, которое из ADT а-ля фримонада вытаскивает множество значений? sealed trait Op[T] object Op { final case class Sum(i: Int, j: Int) extends Op[Long] final case class Div(i: Double, j: Double) extends Op[BigDecimal] } хочу Long :+: BigDecimal :+: Cnil

блин, кажется, нашел :( https://github.com/milessabin/shapeless/pull/561/files

Mikhail
22.09.2017
15:39:03
Ну я как раз и ожидал тегнутый инт, ага. А newtype и теги сильно различаются? У меня что-то руки не дошли почитать.
https://gist.github.com/Rudogma/5f97030ab44d77e71354f025eac161bf ньютайпы конечно прикольны тем, что можно скрыть основание(и за счет этого можно переопределить любые операции которые были у основания) за слоем в компайлтайме (как будто ты сделал новый class Holder(value:Int) , но при этом это все таки не дополнительная обертка в рантайме) и для "уже обьектов" - это по сути ничего и не стоит, но примитивы боксируются в обьекты со всеми вытекающими

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

это про текущие теги и нютайпы. те ``opaque`, что предлагают - похоже, что будут ньютайпами но с доп поддержкой со стороны компилятора, чтобы для примитивов избежать боксинга)

Oleg
22.09.2017
17:16:48
Вот хаскеллисты, как выключить GC в жаве, так они обсуждать. А раз в полгода вопрос возник, так хрен кто

Alexandr
22.09.2017
18:06:57
Господа, я чего-то туплю. Есть Akka-http и мне очень хочется извлечь заголовки по шаблону. Такого напрямую нет, надо писать кастомную директиву. Ок, extractRequest.map(_.headers). К сожалению, на выходе Directive1[Tuple1[Seq[HttpHeaders]]]] В доке сказано: Directive1[Tuple1]] преобразуется в Directive1 имплиситами и они всегда со мной. Но не происходит. Может кто-нибудь рассказать мне, какой я не очень и как правильно? Спасибо.

Наверное, туплю в квадрате. В пятницу. Вечером. Спрашивать про работу.

Alexander
22.09.2017
18:19:47
я тоже боролся с подобными штуками, как в итоге выходило - не помню

Nikolay
22.09.2017
18:27:25
tmap попробуй

Google
Nikolay
22.09.2017
18:28:02
Не точно, но лучше попробуй

Alexandr
23.09.2017
06:17:39
провабол, не помогает. :)

Alexey
23.09.2017
08:07:30
Sergey
23.09.2017
08:07:51
да ладно



Kirill
23.09.2017
08:09:36
как этот шорткат называется чтобы показать тип выражения?

Sergey
23.09.2017
08:10:32
Shift-Ctrl-P у меня на маке (вроде не переопределял с дефолтного кейбинда)

Kirill
23.09.2017
08:11:45
Это разве не показать имплисит параметры?

Alexandr
23.09.2017
08:13:20
def foo: Directive1[immutable.Seq[HttpHeader]] = extractRequest.map(r => r.headers)
В этом выражении у меня выводится тип с Tuple1, принудительное без тепла не компилится

Kirill
23.09.2017
08:13:37
А, на маке ctrl отдельно от cmd что ли

Alexandr
23.09.2017
08:13:43
Что-то напортачил. Странно.

Sergey
23.09.2017
08:14:29
попробуй указать тип явно, без Tuple1

Dmitry
23.09.2017
08:14:33

Страница 950 из 1499