Reputation: 3390
Let's say I have a following method signature in a project using Cats-effect
and tagless final approach:
def schedule[F[_]: Applicative : Async: Timer]
I'm trying to schedule an operation on a schedule
method call using pure FP.
I tried this way:
Timer[F].sleep(FiniteDuration(10, TimeUnit.SECONDS)) *> {
Applicative[F].pure(println("tick"))
}
but it didn't work, because effect println("tick")
gets executed on Timer
initialisation stage.
How can I make it works properly?
Can I also create some kind of recursive construction in order to repeat my scheduled operation each 10 seconds?
Upvotes: 3
Views: 1007
Reputation: 1294
Just using the above to write a full example. Credit to them.
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
}
Upvotes: 3
Reputation: 15086
Applicative[F].pure
doesn't delay the effect. It only lifts a pure value into F
. Since you have an Async
context bound I would suggest Async[F].delay(println("tick"))
.
You can easily call it recursively like this:
def schedule[F[_]: Async: Timer]: F[Unit]
def repeat[F[_]: Async: Timer]: F[Unit] =
schedule >> repeat
Upvotes: 5