New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lifted methods implicitly convert from Option to Iterable but Function1 and PartialFunction do not #9606
Comments
Imported From: https://issues.scala-lang.org/browse/SI-9606?orig=1 |
@szeiger said: vector2.flatMap( _.map(_*2) )
vector2.flatMap( (_.map(_*2)): (Option[Int] => collection.GenTraversableOnce[Int]) ) // inferred type
vector2.flatMap( (_.map(_*2)): (Option[Int] => Option[Int]) ) // wrong An vector2.flatMap( { (x: Option[Int]) => times2a(x) } ) The implicit conversion is applied to the result of the method call, converting an |
@dwijnand said (edited on Jan 19, 2016 10:17:23 PM UTC): I think there's a bug here IMHO. |
Mike Slinn (mslinn) said: |
@szeiger said: If you wrap a function application in another lambda you get the same result: scala> vector2.flatMap { times2b }
<console>:13: error: type mismatch;
found : Option[Int] => Option[Int]
required: Option[Int] => scala.collection.GenTraversableOnce[?]
vector2.flatMap { times2b }
^
scala> vector2.flatMap { x => times2b(x) }
res1: scala.collection.immutable.Vector[Int] = Vector(2, 6, 8) |
@dwijnand said: |
@szeiger said: In order to turn this from a bug report into an improvement request you'd have to specify what to change. The most obvious changes would be to either make both cases work by adding an implicit conversion for functions: // Does not work with current type inference / implicit search rules:
implicit def adaptFunction1[P, R, A](f: P => R)(implicit conv: R => A): (P => A) = (x => conv(f(x))) Or to forbid both by changing eta expansion to typecheck without a return type. You have the same issue for parameters though, so you can either make the rules inconsistent or forbid that as well, which would in turn prevent you from ever eta-expanding an overloaded method. I doubt either of those changes would get very far. |
Mike Slinn (mslinn) said: Over a year ago @odersky said "we want to eliminate some traps that people have found hard in Scala -- so-called puzzlers". Perhaps scalac should recognize specific situations such as this and respond by doing what likely makes most sense to a user, even if it is inconsistent in some more general theoretical sense. |
@som-snytt said: The compiler could emit better advice, or possibly a tool (clippy) could take up the slack. scala> vs.flatMap(f _)
<console>:14: error: type mismatch;
found : () => Option[Int] => Option[Int]
required: Option[Int] => scala.collection.GenTraversableOnce[?]
vs.flatMap(f _)
^
scala> vs.flatMap(o => f(o))
res3: scala.collection.immutable.Vector[Int] = Vector(2)
scala> vs.flatMap(f(_))
res4: scala.collection.immutable.Vector[Int] = Vector(2) |
Seems lifted methods are implicitly converted more readily than Function1 or partial functions. For example, this works as expected:
Using a method that gets lifted to a Function1 also works as expected:
However, attempting to use a Function1 instead of a method produces an error:
The error goes away if the result is converted to an iterator:
The error also goes away if monads are not mixed:
Attempting to use a partial function produces the same error as was encountered for Function1:
Again, the error for the partial function can be avoided by converting to an Iterator.
Again, the error for the partial function can be avoided by not mixing monads.
Is this a bug?
The text was updated successfully, but these errors were encountered: