This perhaps been asked many times before, but none of the suggestions I've found help.
I have a simple Scala code that generates long number that depends on some side-effects. I'm wrapping thing in an IO monad, but according to the least power principle, I'm actually declaring my function as F[_]: Effect
. Now code won't compile and I don't understand why, please suggest what may be wrong
import cats.effect.{Clock, Effect}
import cats.syntax.all._
import java.util.concurrent.TimeUnit
...
def generateId[F[_]: Effect](rid: Long)(implicit F: Effect[F], clock: Clock[F]): F[Long] =
for {
currentTimeNanos <- clock.realTime(TimeUnit.NANOSECONDS)
tid <- F.delay(Thread.currentThread().getId)
} yield
(tid << 40 /* */ & 0xFFFFFF0000000000L) |
(rid << 16 /* */ & 0x000000FFFFFF0000L) |
(currentTimeNanos & 0x000000000000FFFFL)
[error] /.../package.scala:34:41: value flatMap is not a member of type parameter F[Long]
[error] currentTimeNanos <- clock.realTime(TimeUnit.NANOSECONDS)
[error] ^
[error] /.../package.scala:35:34: value map is not a member of type parameter F[Long]
[error] tid <- F.delay(Thread.currentThread().getId)
Also, if you have any suggestions on improving the code, let me know please.
The "flatMap is not a function" error occurs for multiple reasons: Using the flatMap method in a browser that doesn't support it. Using the flatMap method on a value that is not an array. Here is an example of how the error occurs. We called the Array.flatMap () method on an object and got the error back.
We can use a flatMap () method on a stream with the mapper function List::stream. On executing the stream terminal operation, each element of flatMap () provides a separate stream. In the final phase, the flatMap () method transforms all the streams into a new stream.
It's mapper function produces single values for each input value. Use the flatMap () method when the mapper function is producing multiple values for each input value. Use the map () method when the mapper function is producing single values for each input value.
The words stream is a fattened version of all streams into a single stream – consisting of all the words in all the lines. 2. Stream flatMap () Method 2.1. Method Syntax Stream flatMap () method has following syntax. R represents the element type of the new stream.
The problem is that the context bound in F[_]: Effect
desugars into an implicit parameter, so the compiler is seeing something like this:
def generateId[F[_]](rid: Long)(implicit ev: Effect[F], F: Effect[F], ...): F[Long] = ...
That means that every time it tries to resolve an implicit Effect[F]
in the body of the method, it'll fail because it thinks the explicit F
and this synthetic ev
are ambiguous.
The solution is to drop either the context bound or the explicit implicit F: Effect[F]
parameter. I'd suggest killing the context bound, since the fact that Scala allows you to combine the two is part of the reason it's so easy to make this kind of error (and was in my view a serious misjudgement by the language designers, as I've said many times before).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With