I'm trying to make a very simple looping function with a delay using CATS effects (2.0.0-RC1 due to Scala 13).
import cats.effect._
import scala.concurrent.duration.FiniteDuration
object TaskScheduler {
def loop[F[_] : Sync](delay: FiniteDuration, fun: () => F[Unit])
(implicit timer: Timer[F]): F[Unit] =
for {
_ <- timer.sleep(delay)
_ <- fun()
_ <- loop(delay, fun)
} yield ()
}
however, when I try to compile this I get:
sbt:root> tickets/compile
[info] Compiling 15 Scala sources to /home/rohdef/git/smart-tickets/tickets/target/scala-2.13/classes ...
[error] /home/rohdef/git/smart-tickets/tickets/src/main/scala/dk/rohdef/scheduler/TaskScheduler.scala:11:23: value flatMap is not a member of type parameter F[Unit]
[error] _ <- timer.sleep(delay)
[error] ^
[error] /home/rohdef/git/smart-tickets/tickets/src/main/scala/dk/rohdef/scheduler/TaskScheduler.scala:12:15: value flatMap is not a member of type parameter F[Unit]
[error] _ <- fun()
[error] ^
[error] /home/rohdef/git/smart-tickets/tickets/src/main/scala/dk/rohdef/scheduler/TaskScheduler.scala:13:16: value map is not a member of type parameter F[Unit]
[error] _ <- loop(delay, fun)
[error] ^
[error] three errors found
[error] (tickets / Compile / compileIncremental) Compilation failed
[error] Total time: 2 s, completed Aug 10, 2019 1:23:20 PM
sbt:root>
which puzzles me thoroughly, since Sync is a Monad as far as I can see, so both map and flatMap should be present to my knowledge. So, what am I doing wrong?
F
is Sync
then you don't need () => F[Unit]
. It should be equivalent with F[Unit]
@Avasil bingo, thanks a lot :) Now it's giving unrelated error, which I expected :) neat
regarding () => F[Unit]
vs F[Unit]
I have have a def task[F[_]: Concurrent](): F[Unit] = ???
that I'm currently intending to pass to the loop. Would it be better to do loop(task())
rather than loop(task)
, or am I completely missing the point
Future
but fortunately that's not necessary with IO
implementations
F[_]
rather than IO
, cool I like that. But I ran in to an issue, mainly how to do this with a Future
from an external API? I cannot seem to find any general trait having a fromFuture
or similar. How is it best to approach this?
def foo[F[_]: Sync[F]]() = ???
over def foo[F[_]]()(implicit F: Sync[F])
I kind of like the flexibility by the implicit setup, but I was wondering because the tutorial use the former version. Am I doing it bad, is it taste, or?
implicit class richIODatasource[D <: DataSource, F[_]:Sync](val ids: F[D]) extends AnyVal {
import cats.effect.ExitCase.{Completed, Error, Canceled}
def use[T](f: Connection => F[T]): F[T] =
Resource.fromAutoCloseable[F, Connection](ids.map(_.getConnection())).use(c => f(c))
def transaction[T](f:Connection => F[T]):F[T] = use{ c =>
Sync[F].bracketCase(Sync[F].pure(c).map{c =>
c.setAutoCommit(false)
c
})(f){
case (in, Canceled | Error(_)) =>Sync[F].delay(in.rollback())
case (in,Completed) => Sync[F].delay(in.commit())
}
}
}