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?

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top