Size: a a a

Scala User Group

2020 April 15

ЮБ

Юрий Бадальянц in Scala User Group
Yaroslav Sushkov
Подскажите плез, есть два типа: IO1[_] и IO2[_]
как убедить конпелятор, что IO2 можно подставлять вместо IO1, но не наоборот?

чтобы можно было делать вот так:
first: IO1[Unit]
second: IO2[Unit]
first >> second


пробовал:
- в сигнатуре IO2[t] <: IO1[t]
- implicit ev ev: Q ~> M
- implicit ev ev: Q <:< M
- trait AutoTransform[F[_], G[_]] {
 implicit def transform[T](ft: F[T]): G[T]
}
Не лучше ли сделать это через тф?
источник

YS

Yaroslav Sushkov in Scala User Group
Преобразовывать алгебру целиком через mapK, и там, где комбинируется чтобы были алгебры уже все с одной дыркой?
источник

ЮБ

Юрий Бадальянц in Scala User Group
я не совсем понял про mapK и одну дырку, но твоя задача звучит как типичный capability. То есть отдельно описываешь алгебру для запросов, отдельно для мутаций. И потом просишь где нужно либо одно, либо другое, либо оба.
источник

YS

Yaroslav Sushkov in Scala User Group
Юрий Бадальянц
я не совсем понял про mapK и одну дырку, но твоя задача звучит как типичный capability. То есть отдельно описываешь алгебру для запросов, отдельно для мутаций. И потом просишь где нужно либо одно, либо другое, либо оба.
в cats-tagless есть FunctorK с методом mapK (если мне не изменяет память), который позволяет преобразовывать F[_] алгебру в G[_] целиком
источник

YS

Yaroslav Sushkov in Scala User Group
Юрий Бадальянц
я не совсем понял про mapK и одну дырку, но твоя задача звучит как типичный capability. То есть отдельно описываешь алгебру для запросов, отдельно для мутаций. И потом просишь где нужно либо одно, либо другое, либо оба.
В принципе да
источник

ЮБ

Юрий Бадальянц in Scala User Group
Yaroslav Sushkov
в cats-tagless есть FunctorK с методом mapK (если мне не изменяет память), который позволяет преобразовывать F[_] алгебру в G[_] целиком
Сделай один F с разными capability
источник

ЮБ

Юрий Бадальянц in Scala User Group
Без FunctorK
источник

ЮБ

Юрий Бадальянц in Scala User Group
так проще будет
источник

YS

Yaroslav Sushkov in Scala User Group
Просто у меня есть алгебра для запросов, и для мутаций, а реализованы оба интерфейса в одном классе - т.к. кода не очень много, и я уже внутри него хотел использовать разные IO чтобы не было возможности наруканить.
источник

YS

Yaroslav Sushkov in Scala User Group
Юрий Бадальянц
Сделай один F с разными capability
Спасибо, попробую так сделать
источник

NV

Nikita Vilunov in Scala User Group
Друзья, а для дотти есть аналог lampepfl/dotty-example-project, но с новым синтаксисом?
источник

Oℕ

Oleg ℕizhnik in Scala User Group
А там же кода нет практически
источник

Oℕ

Oleg ℕizhnik in Scala User Group
Зачем тебе новый синтаксис в экзампле
источник

NV

Nikita Vilunov in Scala User Group
Чтобы понять как он выглядит хотя бы, я не знаю как даже хелло-ворлд на нём написать
источник

Oℕ

Oleg ℕizhnik in Scala User Group
источник

Oℕ

Oleg ℕizhnik in Scala User Group
источник

NV

Nikita Vilunov in Scala User Group
-language:Scala2Compat ломает новый синтаксис?
источник

AS

Alex Sh in Scala User Group
Python
Как раз недавно использовал State для похожего теста. Мне понравилось.

Вопрос: а если так уж надо гарантировать, то может лучше без тестов гарантировать на уровне типов? Чтобы нельзя было вызвать в неправильном порядке? Ну типа чтобы вызов toKafka можно было сделать только на том что _уже_ вызвало toDb?
Насколько я понимаю, то на уровне типов в Скале нельзя гарантировать exactly-once вызовы методов.
Только at-least-once

def handle[F[_]: Monad](
 toDB: String => F[DBUnit],
 toKafka: (DBToken, String) => F[KafkaUnit],
 toLog: (KafkaUnit, String) => F[LogUnit]
): String => F[(DBUnit, KafkaUnit, LogUnit)] = { in =>
 for {
   dbUnit    <- toDB(in)
   kafkaUnit <- toKafka(dbUnit, in)
   // can't catch this faulty call with types
   _         <- toKafka(dbUnit, in)
   logUnit   <- toLog(kafkaUnit, in)
 } yield (dbUnit, kafkaUnit, logUnit)
}


Без linear types в этом случае никак
источник

D

Daniel in Scala User Group
Alex Sh
Насколько я понимаю, то на уровне типов в Скале нельзя гарантировать exactly-once вызовы методов.
Только at-least-once

def handle[F[_]: Monad](
 toDB: String => F[DBUnit],
 toKafka: (DBToken, String) => F[KafkaUnit],
 toLog: (KafkaUnit, String) => F[LogUnit]
): String => F[(DBUnit, KafkaUnit, LogUnit)] = { in =>
 for {
   dbUnit    <- toDB(in)
   kafkaUnit <- toKafka(dbUnit, in)
   // can't catch this faulty call with types
   _         <- toKafka(dbUnit, in)
   logUnit   <- toLog(kafkaUnit, in)
 } yield (dbUnit, kafkaUnit, logUnit)
}


Без linear types в этом случае никак
поэтому весь процессинг должен быть идемпотентным
источник

AS

Alex Sh in Scala User Group
Daniel
поэтому весь процессинг должен быть идемпотентным
Оч. желательно, но к указанной выше проблеме это относится опосредовано.
источник