Как настроить таймер кошек на абстрактный эффект
Скажем, у меня есть следующая подпись метода в проекте, использующем Cats-effect
и окончательный подход без тегов:
def schedule[F[_]: Applicative : Async: Timer]
Я пытаюсь запланировать операцию на schedule
вызов метода с использованием чистого FP.
Я пробовал так:
Timer[F].sleep(FiniteDuration(10, TimeUnit.SECONDS)) *> {
Applicative[F].pure(println("tick"))
}
но это не сработало, потому что эффект println("tick")
казнен на Timer
этап инициализации.
Как я могу заставить его работать правильно?
Могу ли я также создать какую-то рекурсивную конструкцию, чтобы повторять запланированную операцию каждые 10 секунд?
2 ответа
Applicative[F].pure
не задерживает эффект. Он только увеличивает чистую ценностьF
. Поскольку у вас естьAsync
привязанный к контексту, я бы предложил Async[F].delay(println("tick"))
.
Вы можете легко вызвать это рекурсивно так:
def schedule[F[_]: Async: Timer]: F[Unit]
def repeat[F[_]: Async: Timer]: F[Unit] =
schedule >> repeat
Просто используя приведенное выше, чтобы написать полный пример. Кредит им.
package com.example.timerapp
import cats.Applicative
import cats.effect.{Async, ExitCode, IO, IOApp, Timer}
import cats.syntax.apply._
import cats.syntax.flatMap._
import scala.concurrent.duration._
import java.time.Instant
object TimerApp extends IOApp {
override def run(args: List[String]): IO[ExitCode] = {
repeat[IO].as(ExitCode.Success)
}
def schedule[F[_]: Applicative: Async: Timer]: F[Unit] =
Timer[F].sleep(1 second) *> {
Async[F].delay(println(Instant.now.toString))
}
def repeat[F[_]: Async: Timer]: F[Unit] =
schedule[F] >> repeat
}