you're right, changing that line to
o.fold(fail("c"), _ => succeed, _ => fail("s"))
also compiles, but the test succeeds as expected
_ =>
but failed the test
fail
to be evaluated ¯_(ツ)_/¯
hi guys, I have a problem with cats-effect tracing. I have actually never successfully used it. Maybe you can help:
libraryDependencies += "org.typelevel" %% "cats-core" % "2.3.0" withSources()
libraryDependencies += "org.typelevel" %% "cats-effect" % "3.1.1" withSources()
javaOptions += "-Dcats.effect.tracing.mode=full"
javaOptions += "-Dcats.effect.tracing.buffer.size=128"
javaOptions += "-Dcats.effect.tracing.exceptions.enhanced=true"
fork := true // if that's important I don't know
I used the example provided at https://typelevel.org/cats-effect/docs/tracing, and added the following snippet into the for-comprehension to check that the system property is actually set:
_ <- IO {
import scala.collection.JavaConverters._
val properties = System.getProperties().asScala
for ((k,v) <- properties) println(s"key: $k, value: $v")
}
i.e., this prints:
|| [info] key: cats.effect.tracing.mode, value: full // and the other keys, too
still, I'm getting just the regular stacktrace, nothing augmented. Completely at loss what else I could do.
somethingThatReturnsAnF.map
won't be able to find map. Is there a way to avoid this?
case class MyException(msg: String) extends Throwable
def handleOnlyMy[F[_], A](f: F[A], fallback: F[A])(implicit F: MonadError[F, MyException]) =
f.handleErrorWith(_ => fallback)
val io: IO[Int] = ???
handleOnlyMy(io, 42)
Turned out to be some library versioning issues. This is the upgrade permutation that worked for me:
"org.typelevel" % "cats-mtl_2.13" % "1.0.0",
"com.olegpy" % "meow-mtl-core_2.13" % "0.5.0",
// "com.olegpy" % "meow-mtl-effects_2.13" % "0.5.0" // <-- error
note meow-mtl-effects was incompatible, but not required for my specific use of the library for error handling.
Thanks for the response @arosien !
Hi everybody, I'm new to cats-effect and I'm trying to measure the execution time for a process, I wrote this but I'm not sure if this is the correct way to do it, I particularly wonder whether IO.delay
could affect the measurement due to a potential context shift when computing start/end
and when executing the actual input
function:
def trackExecutionTime[T](input: IO[T])(f: Long => IO[Unit]): IO[T] = {
for {
start <- IO.delay(System.currentTimeMillis())
result <- input
end <- IO.delay(System.currentTimeMillis())
_ <- f(end - start)
} yield result
}
I understand that it would be ideal to replace the current time function by using a Clock
instance but I believe it shouldn't matter for now.
Thanks.
if course it will not measure the duration of a failing input computation. depending on your needs, that's fine though.
I'm aware, for this case I just care about successful outcomes
looks correct to me. and yes, a Clock would be better. i'd probably at least use java.time.Instant.now instead of System.currentTimeMillis, if i went without a Clock.
Thanks, I was worried about potential context-shifts affecting the measurement
Temporal[F].sleep(1.second)
and force them to schedule any suspendable action in the background or on a different fiber than the one that function was executed on.
Hello, am new to cats-effects and am confused about something
trait CampaignOpsResult {
def message: String
}
case class CampaignOperationError(message: String) extends CampaignOpsResult
case class CampaignCreated(message: String = "Campaign Successfully created") extends CampaignOpsResult
val rr = for {
db <- client
coll <- db.getCollectionWithCodec[Campaign]("docs")
existing: Option[Campaign] <- coll.find.filter(Filter.eq("campaignName", campaign.campaignName)).first
writeResult: F[CampaignOpsResult] = if(existing.nonEmpty) CampaignOperationError("Campaign with that name exists before").pure
else {
for {
res <- coll.insertOne(campaign)
resp: CampaignOpsResult = if(res.wasAcknowledged()) CampaignCreated() else CampaignOperationError("Unable to create campaign")
} yield resp
}
res <- writeResult
} yield res
now i expect the writeResult
variable to be a valid F[CampaignOpsResult]
but everytime i tried get this error
polymorphic expression cannot be instantiated to expected type;
found : [F[_]]F[CampaignOperationError]
required: F[CampaignOpsResult]
writeResult: F[CampaignOpsResult] = if(existing.nonEmpty) CampaignOperationError("Campaign with that name exists before").pure
Pls any advice is appreciated
val signal1 = Stream.repeatEval(producer("A", 100.millis))
val signal2 = Stream.repeatEval(producer("B", 200.millis))
val signal: Stream[IO, String] = signal1.merge(signal2)
class Bulb(ref: Ref[IO, Int]) {
def toggle(): IO[Unit] = IO.println(("toggle")) >> IO.unit //todo
}
def pipes(bulb: Bulb): Pipe[IO, String, String] = in =>
in.evalMap(signal => bulb.toggle() >> IO("Toggled"))
val ioBulb: IO[Bulb] = for {
r <- Ref[IO].of(0)
b = new Bulb(r)
} yield b
ayeo (ayeo) assuming every toggle sets the internal Ref to either 1 or 0, you can do something like this.
object Main extends IOApp.Simple:
val signal1 = Stream.emit[IO, String]("A").metered(100.millis)
val signal2 = Stream.emit[IO, String]("B").metered(200.millis)
def run: IO[Unit] =
Bulb.make[IO].flatMap { bulb =>
signal1
.merge(signal2)
.evalMap(_ => IO.println("toggle") *> bulb.toggle)
.interruptAfter(5.seconds)
.compile
.drain
}
trait Bulb[F[_]]:
def toggle: F[Unit]
object Bulb:
def make[F[_]: Functor: Ref.Make]: F[Bulb[F]] =
Ref[F].of(0).map { ref =>
new:
def toggle: F[Unit] = ref.update(x => if x == 0 then 1 else 0)
}
Sleeps and timeouts don't work so well in the browser but you can see the compiling version here: https://scastie.scala-lang.org/NXdBGJLZTwyJeFh3tsgIwg