Scala中的内联函数歧义

use*_*304 4 scala function

当一个操作符被提升为一个定义的高阶函数之一时,Scala允许非常简洁的语法,例如(请忽略它可以简化为.product())的事实:

List(1,2,3).fold(1)(_ * _)
Run Code Online (Sandbox Code Playgroud)

到上面我可以通过 _ \* _

但是在定义了我自己的玩具函数zipWith()之后,我需要在传递函数时非常明确:

implicit class EnrichedList[A](val self: List[A]) extends AnyVal {
  def zipWith[B, C](that: List[B])
                   (implicit zipper: A => B => C): List[C] = {

    def zipWithHelper(zipper: A => B => C)
                     (as: List[A])
                     (bs: List[B]): List[C] = {
      (as, bs) match {
        case (_, Nil) => Nil
        case (Nil, _) => Nil
        case (a :: restOfA, b :: restOfB) =>
          zipper(a)(b) :: zipWithHelper(zipper)(restOfA)(restOfB)
      }
    }

    zipWithHelper(zipper)(self)(that)
  }
}
Run Code Online (Sandbox Code Playgroud)

这个:List(1, 3, 4).zipWith(List(3, 4, 5))(_ * _)不行,说

错误:(60,46)缺少扩展函数的参数类型((x $ 1:,x $ 2)=> x $ 1. $ times(x $ 2))List(1,3,4).zipWith(List(3,4) ,5))(_*_)

我需要说明函数采用什么类型的参数:

List(1, 3, 4).zipWith(List(3, 4, 5))((x: Int) => (y: Int) => x * y)
Run Code Online (Sandbox Code Playgroud)

为什么编译器不允许我传递速记版本_ * _

And*_*kin 6

表达式_ * _不是简写(x: Int) => (y: Int) => x * y.这是一个简写(x: Int, y: Int) => x * y.如果更改的类型zipper(A, B) => C代替的A => B => C,它应该工作.Currying是一件事,它不仅仅是身份功能的奇特名称.

这里编译:

implicit class EnrichedList[A](val self: List[A]) {
  def zipWith[B, C](that: List[B])
                   (implicit zipper: (A, B) => C): List[C] = {

    def zipWithHelper(zipper: (A, B) => C)
                     (as: List[A])
                     (bs: List[B]): List[C] = {
      (as, bs) match {
        case (_, Nil) => Nil
        case (Nil, _) => Nil
        case (a :: restOfA, b :: restOfB) =>
          zipper(a, b) :: zipWithHelper(zipper)(restOfA)(restOfB)
      }
    }

    zipWithHelper(zipper)(self)(that)
  }
}

println( List(1, 3, 4).zipWith(List(3, 4, 5))(_ * _) )
Run Code Online (Sandbox Code Playgroud)

和打印

List(3, 12, 20)
Run Code Online (Sandbox Code Playgroud)

  • @ user3681304有一个方法`.curried`.示例:`val f =(x:Int,y:Int)=> x + y; f.curried`.但是curried函数没有下划线占位符语法. (2认同)