Scalaz Implicit Resolution Confusion

74 views Asked by At

I'm running into a situation with Scalaz that's confusing me a bit. Let's say we have the following types defined.

import scalaz.*
import Scalaz.*

type Example[A] = Unit \/ Success[A]

case class Success[+A](val exampleField: A)

So Example is either a left Unit or a right Success[A], where Success is a trivial wrapper around an A.

Now, I want to write a function which is basically Scalaz's monadic bind operator on Example.

def doBind[A, B](a: Example[A])(f: Success[A] => Example[B]): Example[B] =
  a.flatMap(f)

Looks great. Scala's flatMap is basically the monadic bind operator, and this all typechecks.

However, if I try to use the Scalaz >>= bind operator here as follows

def doBind[A, B](a: Example[A])(f: Success[A] => Example[B]): Example[B] =
  a >>= f

then we get

[error] 12 |  a >>= f
[error]    |  ^^^^^
[error]    |  value >>= is not a member of com.mercerenies.fictional.Example[A].
[error]    |  An extension method was tried, but could not be fully constructed:
[error]    |
[error]    |      scalaz.Scalaz.ToBindOpsUnapply[com.mercerenies.fictional.Example[A]](a)(
[error]    |        scalaz.Unapply.unapplyMAB1[TC, M0, A0, B0](scalaz.\/.DisjunctionInstances1[Nothing])
[error]    |      )

On the other hand, if we remove the Success and have our Example directly be a right A as

type Example[A] = Unit \/ A

def doBind[A, B](a: Example[A])(f: A => Example[B]): Example[B] =
  a >>= f

then the >>= works. So why doesn't it work if we have a Success case class wrapper around our value? My understanding is that >>= is coming from an implicit instance of BindOps, so why does it work in the A case but not the Success[A] case?

Running Scala 3.0.0 with Scalaz 7.4.0-M7.

0

There are 0 answers