Kleisli Inference in scala with cats

Viewed 41

Quick question

With

trait SubEnv1
trait SubEnv2

While i understand (I think) why the following code would work:

    def logic  =
        for {
            s1  <- Kleisli{(e:SubEnv1) => Option("hello")}
            s1  <- Kleisli{(e:Any) => Option("hello2")}
        } yield (s1)
//cats.data.Kleisli[Option,SubEnv1,String]

I am confused as to why the following does not work:

def logic  =
    for {
        s1  <- Kleisli{(e:SubEnv1) => Option("hello")}
        s1  <- Kleisli{(e:Nothing) => Option("hello2")}
    } yield (s1)

//type mismatch;
//found   : Nothing => Option[String]
//required: A => Option[String]

In fact i do not understand the error.

The type of flatMap is

def flatMap[C, AA <: A](f: B => Kleisli[F, AA, C])(implicit F: FlatMap[F]): Kleisli[F, AA, C]

So we have AA <: A

  1. The first work because of contravariance i think. Where AA => Option[C] is expected we can pass can take Any => Option[C]

  2. The second is rather strange given the requirement AA <: A and

implicitly[Nothing <:< SubEnv1]
// Nothing <:< SubEnv1 = generalized constraint

So what does //required: A => Option[String] that it requires a type but Nothing ?

1 Answers

I believe you are simply hitting this bug: Nothing does not conform to arbitrary type parameter #9453

Proof:

Kleisli { (e: SubEnv1) => Option("hello") }.flatMap[String, Nothing] { s1 =>  
    Kleisli[Option, Nothing, String] { (e: Nothing) => Option("boo") }
}
res34: Kleisli[Option, Nothing, String] = Kleisli(cats.data.Kleisli$$$Lambda$2297/0x0000000800c08840@1385e9e3)

(typechecks correctly)

Related