I'm trying to learn functional random from cats. This is method inside big class:
def prepareDate(order: Model, zoneId: String): F[Instant] =
Random[F].betweenLong(7200, 21600).flatMap { seconds =>
order.dateTime
.plusSeconds(seconds)
.toInstant(ZoneOffset.of(zoneId))
.asInstanceOf[F[Instant]]
}
it not compiles with No given instance of type cats.effect.std.Random[F] was found for parameter ev of method apply in object Random. error
I've tried to put Random inside this way:
class SomeClass[F[_]: Async: Logger: Random]
but have no idea how to implicit it in object-companion.
Let's remove some of the fluff, since the logic itself is irrelevant for the problem:
So... What's
F[_]? Compiler will ask you the same question.If you had some concrete instance of
F[_], for examplecats.IO, then the whole thing would be simple. You would just need to obtain an instance ofRandom[IO]to work with, which can be done with e.g.Random.scalaUtilRandom[IO](this gives anIO[Random[IO]]hence theflatMap):So what your question really comes down to is - given that you don't know what the user of
prepareDatewill be using asF[_](it could beIOor something else), how do you intend to prove that there will be aRandom[F]available in scope?Your
F[_]is probably a generic parameter in the context where yourprepareDatemethod is defined. In case it's a class, then what you wrote would be correct -class SomeClass[F[_]: Random]means thatFhas to be a higher-kinded type (due to[_]) and there has to be aRandom[F]available in scope. Whoever is instantiating a concrete instance ofSomeClasswith some concreteF[_]will have to make sure thatRandom[F]is in scope.Here's some complete code:
You mentioned having a companion object, but that doesn't change much in the concept itself - you just move "I need some
F[_]that has aRandom[F]in scope" from your class definition, to your method definition:Btw in case it helps you or someone else:
[F[_] : Random]is just syntactic sugar for the implicit parameter of type[Random[F]]. This works equally fine, it's just more verbose: