Implicit climb in scala

I want to implicitly convert functions from A => Bto List[A] => List[B].

I wrote the following implicit definition:

implicit def lift[A, B](f: A => B): List[A] => List[B] = ...

Unfortunately, when I write the following code, implicit are not applied:

val plusOne: (List[Int]) => List[Int] = (x: Int) => (x + 1)

If I annotate a function with an explicit time, it works fine.

Why? How can i fix this?

UPDATE The problem seems to be related to anonymous functions. For comparison:

@Test
def localLiftingGenerics {
  implicit def anyPairToList[X, Y](x: (X, Y)): List[X] => List[Y] = throw new UnsupportedOperationException  

  val v: List[String] => List[Int] = ("abc", 239)
}

@Test
def localLiftingFuns {
  implicit def fun2ListFun[X, Y](f: X => Y): List[X] => List[Y] = throw new UnsupportedOperationException

  val v: List[String] => List[Int] = ((x: String) => x.length)
}

The first is compiled. The second is marked as error

+5
source share
4 answers

According to Scala Language Specification / Expressions / Anonymous Functions (6.23):

If the expected type of anonymous function is of the form scala.Function n [ S 1, & hellip ;, S n, R], of e R...

, List[Int], ( ):

val function = (x: Int) => (x + 1)
val plusOne: (List[Int]) => List[Int] = function

:

val plusOne: (List[Int]) => List[Int] = ((x: Int) => (x + 1)): Int => Int
+6

(Scala 2.9.1-1 (Java- HotSpot (TM), 64- VM, Java 1.7.0_05)

: fun2ListFun , , `` fun2ListFun,

found   : String => <error>
 required: List[String] => List[Int]

Note that implicit conversions are not applicable because they are ambiguous:
 both method fun2ListFun2 of type [X, Y](f: X => Y)List[X] => List[Y]
 and method fun2ListFun of type [X, Y](f: X => Y)List[X] => List[Y]
 are possible conversion functions from String => <error> to List[String] => List[Int]
  val v: List[String] => List[Int] = ((x: String) => x.length)

, implicits .


:

val v: List[String] => List[Int] = ((x: String) => x.length) /* Error*/

val f = ((x: String) => x.length)
val v: List[String] => List[Int] = f /* Works */

.

+1

.

 def localLiftingFuns {
   implicit def fun2ListFun[X, Y](f: X => Y): List[X] => Y = throw new UnsupportedOperationException

   val v: List[String] => Int = ((x: String) => x.length)
 }

:

 def localLiftingFuns {
   implicit def fun2ListFun[X, Y](f: X => List[Y]): List[X] => List[Y] = throw new UnsupportedOperationException
   implicit def type2ListType[X](x:X): List[X] = throw new UnsupportedOperationException

   val v: List[String] => List[Int] = ((x: String) => x.length)
 }

.

+1

, , . , :

scala> implicit def lift[A,B](f: A => B) = (_:List[A]).map(f)
lift: [A, B](f: (A) => B)(List[A]) => List[B]

scala> val f: List[Int] => List[Int] = ((_:Int) + 1):(Int => Int)
f: (List[Int]) => List[Int] = <function1>
0

All Articles