tags:

views:

78

answers:

2

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?

+3  A: 

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))
Ben Lings
I see - I knew it was something to do with the fact that Set extends `A => Boolean`. The implicit you specify creates an `MA[M[_], A]` from a `Function`[I, R]`. `M[_]` is inferred as the `PartialApply1Of2` which makes the second type argument to `MA` be `R`. `R` is of course the return type of the `Function1` which is `Boolean` in this case.
oxbow_lakes
+2  A: 

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.

retronym
I think that there should also be a "cleaner" Set-based implementation for the member methods - i.e. that they do not use `FoldRight` but rather use the fact that a `Set` is a `A => Boolean`. Not that I have any idea how to do this :-)
oxbow_lakes