Кошки имеют функцию FunctionK, которая является естественным преобразованием.
Я сделал это:
На вершине мира, где все построено, вам понадобится это
val liftToConnIO: FunctionK[IO, ConnectionIO] = LiftIO.liftK[ConnectionIO]
В классе, нуждающемся в преобразовании из F [String] в G [String] (F будет IO, G будет ConnectionIO, когда вы создаете все), вы можете передать liftToConnIO
и использовать его для преобразования F [A ] до G [A], где это необходимо.
Классу, который не хочет абстрагироваться через IO и ConnectionIO, можно передать FunctionK для выполнения подъема:
class Stuff[F[_], G[_]](emailer: Emailer[F], store: Store[G], liftToG: FunctionK[F, G]) {
def sendEmail: G[Unit] =
for {
_ <- doDatabaseThingsReturnStuffInG
_ <- liftToG(emailer.sendEmail)
_ <- doMoreDatabaseThingsReturnStuffInG
} yield ()
}
(Вы можете нужны границы контекста (Syn c?) для F и G)