Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

value flatMap is not a member of type parameter F[Long] when using cats.effect

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.

like image 445
edio Avatar asked Feb 18 '19 04:02

edio


People also ask

Why is flatMap not a function?

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.

How to use flatMap () method on a stream in Java?

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.

What is the difference between map () and flatMap () methods in mapper?

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.

What is stream flatMap in R?

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.


Video Answer


1 Answers

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).

like image 97
Travis Brown Avatar answered Nov 15 '22 03:11

Travis Brown