An implicit conversion of a function to a second-order function only works if the conversion function has at least two parameters

I have a problem with implicit conversions and higher order functions. It seems that the implicit conversion of a function into a second-order function only works if the conversion function has at least two parameters.

Working:

implicit def conv(foo: Integer => String): String => String = null 

Does not work:

 implicit def conv(foo: Integer => String): String => String => String = null 

Working:

 implicit def conv(foo: (Integer, Integer) => String): String => String => String = null 

Full example with a point of failure:

 { implicit def conv(foo: Integer => String): String => String = null def baadf00d(foo: Integer): String = null def deadbeef(foo: String => String) = null deadbeef(conv(baadf00d)) deadbeef(baadf00d) } { implicit def conv(foo: Integer => String): String => String => String = null def baadf00d(foo: Integer): String = null def deadbeef(foo: String => String => String) = null deadbeef(conv(baadf00d)) deadbeef(baadf00d) // <-------- DOES NOT COMPILE! } { implicit def conv(foo: (Integer, Integer) => String): String => String => String = null def baadf00d(foo: Integer, bar: Integer): String = null def deadbeef(foo: String => String => String) = null deadbeef(conv(baadf00d)) deadbeef(baadf00d) } 

What am I missing?

Thanks!

+7
scala implicit-conversion higher-order-functions
source share
2 answers
  implicit def conv(foo: Integer => String): String => String => String = ??? def baadf00d(i: Integer): String = ??? def goodf00d: Integer => String = _ => ??? def deadbeef(foo: String => String => String) = ??? deadbeef(conv(baadf00d)) deadbeef(baadf00d) // <-------- DOES NOT COMPILE! deadbeef(goodf00d) // <-------- COMPILE! // ยฏ\_(ใƒ„)_/ยฏ 

The problem is how implicit conversions work on Scala and that there are exact and broken functions in Scala.

This is what SHOULD work, but not, and probably this is another compiler error (get ready to meet many others as you use Scala more and more).

EDIT: Regarding your last example

 implicit def conv(foo: (Integer, Integer) => String): String => String => String = null def baadf00d(foo: Integer, bar: Integer): String = null def deadbeef(foo: String => String => String) = null 

This is because function definitions exist. It is believed that the function (Int, Int) => String and the definition of the normal method (uneven) in scala, like how baadf00d defined, turns into this.

For example, the function:

 def f(a: Int, b: Int): String 

It turned into

 (Int, Int) => String 

Please note that 2 Ints are loaded! This is NOT the same as:

 Int => Int => String 

If you want to override baadf00d in:

 def baadf00d: Integer => Integer => String = _ => _ => ??? 

This code will not compile because baadf00d is now โ€œdifferentโ€, although it does the same.

For more information, review the definition of objects:

 Function1, Function2, Function3 .... 

http://www.scala-lang.org/api/current/#scala.Function2

+3
source share
 implicit def conv1(a: Function1[Int, String]): Function2[String, String, String] = null def baadf00d1(i: Int): String = null def deadbeef1(arg: Function2[String, String, String]) = null deadbeef(baadf00d) // compiles 

This is a conversion between A => B and Function1[A,B] that does not occur.

There is also a Function type in Predef - note the type differences here:

 scala> val f1: Function[Int, Int] = null f1: Function[Int,Int] = null scala> val f2: Function1[Int, Int] = null f2: Int => Int = null scala> :type f1 Function[Int,Int] scala> :type f2 Int => Int 

This is an alias of Function1 , but with different type restrictions (as indicated in the comments below).

-one
source share

All Articles