Skip to content
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

Surprising interaction of eta-expansion and implicit argument passing #7641

Open
scabug opened this issue Jul 8, 2013 · 8 comments
Open
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) implicit typer
Milestone

Comments

@scabug
Copy link

scabug commented Jul 8, 2013

e.g.

def foo[T: Monoid](i:T) = null

(using scalaz's Monoid typeclass) or

def bar[T : scala.math.Ordering](t:T) = null

, then

Some(5) map foo

(or bar) gives "No implicit Monoid defined for T" (or Ordering).
Variants that do work:

Some(5) map foo[Int]
Some(5).map[Null](foo)
Some(5) map (x=>foo(x))

Also, this doesn't appear to affect functions using [T : ClassTag] - that's resolved just fine.

@scabug
Copy link
Author

scabug commented Jul 8, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7641?orig=1
Reporter: Leif Warner (pdxleif)

@scabug
Copy link
Author

scabug commented Jul 8, 2013

Leif Warner (pdxleif) said:
This works fine in Haskell (and Idris), btw.

@scabug
Copy link
Author

scabug commented Jul 8, 2013

Leif Warner (pdxleif) said:
Additional example:
https://gist.github.com/edrex-janrain/5946323

@scabug
Copy link
Author

scabug commented Jul 9, 2013

@retronym said:
Standalone:

object Test {
  trait TC[_]
  implicit val tcInt: TC[Int] = ???
  def bar[T](t:T)(implicit x: TC[T]): Int = 0
  def foo[B](f: Int => B) {}
  foo (x => bar(x)) // okay
  foo (bar) // fails
}

@scabug
Copy link
Author

scabug commented Jul 9, 2013

@retronym said:
Leaving away the explicit type of the anonymous function's parameter x triggers it to be inferred as Int:

6.23 Anonymous functions

If the expected type of the anonymous function is of the form scala.Functionn[S1,...,Sn, R], the expected type of e is R and the type Ti of any of the parameters xi can be omitted, in which case Ti = Si is assumed.

Eta expansion drives the type of the parameter from the MethodType being expanded:

Second, one creates a fresh name yi for every argument type Ti of the method (i = 1, ..., n). The result of eta-conversion is then:

{
   val x1 = e1; ... val xm = em;
  (y1:T1,...,yn:Tn) => e′(y1,...,yn) 
}

In the example about, that gives:

(t: T) => bar(t)

where T is an abstract type corresponding to the method type parameter.

I'm not sure yet whether we can make the two behave uniformly. I'll leave this ticket open in the hope that someone finds a way.

For future reference, the interesting stuff is in instantiateToMethodType, instantiateToMethodType, and etaExansion.

Even though the expected type is Int => Int, we

@scabug
Copy link
Author

scabug commented Jul 10, 2013

Leif Warner (pdxleif) said:
Did your last comment get cut off?

Other cases:

Some(Some("yes")).map(_.orNull) // works

def orNull[A](o:Option[A])(implicit ev: <:<[Null,A]): A = o getOrElse null
Some(Some("yes")).map(orNull) // doesn't

@scabug
Copy link
Author

scabug commented Jun 7, 2015

@lrytz
Copy link
Member

lrytz commented Apr 23, 2018

@adriaanm you might want to look at this in your work on eta-expansion

@lrytz lrytz modified the milestones: 2.13.0-M4, 2.13.0-M5 Apr 23, 2018
@adriaanm adriaanm modified the milestones: 2.13.0-M5, 2.13.0-RC1 Aug 8, 2018
@adriaanm adriaanm modified the milestones: 2.13.0-RC1, Backlog Jan 8, 2019
@SethTisue SethTisue added the fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) label Jan 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) implicit typer
Projects
None yet
Development

No branches or pull requests

6 participants