Compilation issues using scalaz's MA methods on Set but not List
Question
The following compiles just fine using scala Beta1 and scalaz snapshot 5.0:
val p1: Int => Boolean = (i : Int) => i > 4
val s: List[Int] = List(1, 2, 3)
val b1 = s ∃ p1
And yet this does not:
val s: Set[Int] = Set(1, 2, 3)
val b1 = s ∃ p1
I get the following error:
Found: Int => Boolean
Required: Boolean => Boolean
The signature of the ∃
method is:
def ∃(p: A => Boolean)(implicit r: FoldRight[M]): Boolean = any(p)
And there should be an implicit SetFoldRight
in scope. It is exactly the same for the methods: ∀
, ∋
and ∈:
- what is going on?
Solution
It looks like the A
in MA[M[_],A]
is Boolean
for a Set
. In the Scalaz
object, there is the following implicit:
implicit def Function1ApplyMA[A, R](f: A => R): MA[PartialApply1Of2[Function1, A]#Apply, R] = ma[PartialApply1Of2[Function1, A]#Apply, R](f)
Now I don't fully understand what's going on with the types here, but it looks like the A
in MA[M[_],A]
is the return type of the Function1
. Set[A]
extends A => Boolean
, hence why A
in the definition of ∃
is being inferred to Boolean
.
One fix is to use the explicit ma
method to convert the Set into an MA
, rather than let implicits do the heavy lifting:
val s = ma(Set(1, 2, 3))
OTHER TIPS
I need to add this to object Scalaz
:
implicit def SetMA[M[_] <: Set[_], A](s: M[A]): MA[M, A] = ma[M, A](s)
But, thanks to #2741, I'm running into a problem making this higher priority than the offending conversion:
implicit def Function1ApplyMA[A, R](f: A => R): MA[PartialApply1Of2[Function1, A]#Apply, R] = ma[PartialApply1Of2[Function1, A]#Apply, R](f)
I really wish that Seq
and Set
were implicitly convertible to Function1
rather than inheriting from it.
UPDATE
This is now fixed.