Size: a a a

Scala User Group

2020 November 30

VS

Vladimir Sapronov in Scala User Group
λoλcat
Чтобы люди реже использовали
Это не объясняет почему это плохо. Ну кроме того, что дизайнерам скала они не нравятся.
Я готов там почитать что-то, если есть какое-то внятное объяснение.
Просто в других частях фп (где нет АДТ) люди часто передают ф-ции налево и направо. Ф-ция - first class citizen, higher order functions подразумевают это. Нодо как-то обосновать прям, что тайпклассы лучше потому-то и потому-то... Я бы с удовольствием внял бы такому обоснованию.
источник

λ

λoλcat in Scala User Group
Vladimir Sapronov
Это не объясняет почему это плохо. Ну кроме того, что дизайнерам скала они не нравятся.
Я готов там почитать что-то, если есть какое-то внятное объяснение.
Просто в других частях фп (где нет АДТ) люди часто передают ф-ции налево и направо. Ф-ция - first class citizen, higher order functions подразумевают это. Нодо как-то обосновать прям, что тайпклассы лучше потому-то и потому-то... Я бы с удовольствием внял бы такому обоснованию.
С удовольствием бы объяснил. Но лучше Обербского посмотреть
источник

VS

Vladimir Sapronov in Scala User Group
Kirill Shelopugin
Почему нельзя-то? Вот ты же сделал, напиши рядом второй энам и из строки в него парси той же функцией read
Ну вот придется для каждого енама написать:
implicit val decodeChoice1: (String => Choice1) = StringCodecs.decodeStringEnum[Choice1]
implicit val decodeChoice2: (String => Choice2) = StringCodecs.decodeStringEnum[Choice2]
implicit val decodeChoice3: (String => Choice3) = StringCodecs.decodeStringEnum[Choice3]
....
implicit val decodeChoice30: (String => Choice30) = StringCodecs.decodeStringEnum[Choice30]
источник

M

Mikhail in Scala User Group
Vladimir Sapronov
Отдельный вопрос: почему лучше сделать reader тайпклассом. Я не спорю, но это не очевидно, чем это лучше? Но это не главный вопрос.... Я в принципе понимаю и так и так.

Т.е. мое опасение, что не специфицировать тип каждого енама не прокатит - это я правильно боялся?
Все прокатит. Я же написал, что если ты перейдешь к моему варианту, то скорее всего вопрос отпадет сам. Вот держи https://scastie.scala-lang.org/rudogma/DqdoIKdaSs6Mb5gtCyeUwQ/8
источник

λ

λoλcat in Scala User Group
Vladimir Sapronov
Ну вот придется для каждого енама написать:
implicit val decodeChoice1: (String => Choice1) = StringCodecs.decodeStringEnum[Choice1]
implicit val decodeChoice2: (String => Choice2) = StringCodecs.decodeStringEnum[Choice2]
implicit val decodeChoice3: (String => Choice3) = StringCodecs.decodeStringEnum[Choice3]
....
implicit val decodeChoice30: (String => Choice30) = StringCodecs.decodeStringEnum[Choice30]
Все это какая-то нерабочая фигня. Не должен декодер возвращать T. Либо айзер, либо трай, либо что-то ещё, инкапсурующее ошибку
источник

M

Mikhail in Scala User Group
λoλcat
Все это какая-то нерабочая фигня. Не должен декодер возвращать T. Либо айзер, либо трай, либо что-то ещё, инкапсурующее ошибку
Лентяем и фроу сойдет
источник

M

Mikhail in Scala User Group
Mikhail
Лентяем и фроу сойдет
Если очень хочется, то можно
источник

VS

Vladimir Sapronov in Scala User Group
λoλcat
Все это какая-то нерабочая фигня. Не должен декодер возвращать T. Либо айзер, либо трай, либо что-то ещё, инкапсурующее ошибку
Блин это понятно, я максимально код упростил, чтобы говорить о той проблеме с которой застрял
источник

VS

Vladimir Sapronov in Scala User Group
Там у меня Option на самом деле
источник

VS

Vladimir Sapronov in Scala User Group
Mikhail
Все прокатит. Я же написал, что если ты перейдешь к моему варианту, то скорее всего вопрос отпадет сам. Вот держи https://scastie.scala-lang.org/rudogma/DqdoIKdaSs6Mb5gtCyeUwQ/8
Читаю.... пытаюсь понять....
источник

VS

Vladimir Sapronov in Scala User Group
нужно время
источник

M

Mikhail in Scala User Group
Vladimir Sapronov
Читаю.... пытаюсь понять....
Когда ты написал case object Choice extends StringEnum[Choice] то ты добавил в скоуп  
implicit def materialiseStringValueEnum[EntryType <: StringEnumEntry]: StringEnum[EntryType]
, который в ValueEnum.scala в енумератуме. Вот его и можно использовать
источник

VS

Vladimir Sapronov in Scala User Group
Блин и правда работает
источник

VS

Vladimir Sapronov in Scala User Group
Еще вопросик тогда
источник

VS

Vladimir Sapronov in Scala User Group
Я смотрел как circe делает и вижу, что у них требование использовать обязательно with StringCirceEnum[Choice]
на каждом енаме, который хотим кодить через circe.
Вопрос: нафига?
Почему они не могли просто не вмешиваться в определения енамов и определить свою (де)сериализацию сбоку?
источник

VS

Vladimir Sapronov in Scala User Group
Там прямо вот кодеки с конретными типами и прописаны:
trait StringCirceEnum[EntryType <: StringEnumEntry] extends CirceValueEnum[String, EntryType] {
 this: ValueEnum[String, EntryType] =>
 implicit val circeEncoder: Encoder[EntryType] = Circe.encoder(this)
 implicit val circeDecoder: Decoder[EntryType] = Circe.decoder(this)

 implicit val circeKeyEncoder: KeyEncoder[EntryType] = Circe.keyEncoder(this)
 implicit val circeKeyDecoder: KeyDecoder[EntryType] = Circe.keyDecoder(this)
}
источник

KS

Kirill Shelopugin in Scala User Group
Vladimir Sapronov
Ну вот придется для каждого енама написать:
implicit val decodeChoice1: (String => Choice1) = StringCodecs.decodeStringEnum[Choice1]
implicit val decodeChoice2: (String => Choice2) = StringCodecs.decodeStringEnum[Choice2]
implicit val decodeChoice3: (String => Choice3) = StringCodecs.decodeStringEnum[Choice3]
....
implicit val decodeChoice30: (String => Choice30) = StringCodecs.decodeStringEnum[Choice30]
В скасти Михаила всё хорошо, кроме того, что есть аллокация декодера каждый раз. Стандартным подходом для избавления от этого является трейт, от которого ты свой энум будешь наследовать и там будет инстанс тайпкласса один раз аллоцироваться.
Вот пример с двумя энумами. К каждому энуму просто достаточно будет добавлять with StringTheReader[<новый энум>] и получишь инстанс своего тайпкласса.
https://scastie.scala-lang.org/jhbaqic2SuqhMhRC84el6A
источник

KS

Kirill Shelopugin in Scala User Group
О, вот собственно ты и сам докопался до стандартного подхода :)
источник

λ

λoλegΥch in Scala User Group
Vladimir Sapronov
Я смотрел как circe делает и вижу, что у них требование использовать обязательно with StringCirceEnum[Choice]
на каждом енаме, который хотим кодить через circe.
Вопрос: нафига?
Почему они не могли просто не вмешиваться в определения енамов и определить свою (де)сериализацию сбоку?
потому что тогда бы их нельзя было переопределить
источник

VS

Vladimir Sapronov in Scala User Group
Kirill Shelopugin
О, вот собственно ты и сам докопался до стандартного подхода :)
Ахаха - я сижу с этим со вчера.
источник