隐式参数的顺序在Scala中是否重要?

zig*_*tar 5 scala implicit

给出一些方法

def f[A,B](p: A)(implicit a: X[A,B], b: Y[B])
Run Code Online (Sandbox Code Playgroud)

隐式参数列表中的abefore 的顺序b对类型推断是否重要?

我认为只有不同参数列表中的参数放置很重要,例如类型信息仅从左到右通过参数列表流动.

我问,因为我注意到在单隐式列表中更改隐式参数的顺序使得我的程序编译.

真实的例子

以下代码使用:

  • 无形的2.1.0
  • 斯卡拉2.11.5

这是一个简单的sbt构建文件,以帮助编译示例:

scalaVersion := "2.11.5"

libraryDependencies += "com.chuusai" %% "shapeless" % "2.1.0"

scalaSource in Compile := baseDirectory.value
Run Code Online (Sandbox Code Playgroud)

在这个例子上.此代码编译:

import shapeless._
import shapeless.ops.hlist.Comapped

class Foo {
  trait NN
  trait Node[X] extends NN
  object Computation {
    def foo[LN <: HList, N <: HList, TupN <: Product, FunDT]
    (dependencies: TupN)
    (computation: FunDT)
    (implicit tupToHlist: Generic.Aux[TupN, LN], unwrap: Comapped.Aux[LN, Node, N]) = ???
//    (implicit unwrap: Comapped.Aux[LN, Node, N], tupToHlist: Generic.Aux[TupN, LN]) = ???

    val ni: Node[Int] = ???
    val ns: Node[String] = ???
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString)
  }
}
Run Code Online (Sandbox Code Playgroud)

这段代码失败了

import shapeless._
import shapeless.ops.hlist.Comapped

class Foo {
  trait NN
  trait Node[X] extends NN
  object Computation {
    def foo[LN <: HList, N <: HList, TupN <: Product, FunDT]
    (dependencies: TupN)
    (computation: FunDT)
//    (implicit tupToHlist: Generic.Aux[TupN, LN], unwrap: Comapped.Aux[LN, Node, N]) = ???
    (implicit unwrap: Comapped.Aux[LN, Node, N], tupToHlist: Generic.Aux[TupN, LN]) = ???

    val ni: Node[Int] = ???
    val ns: Node[String] = ???
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString)
  }
}
Run Code Online (Sandbox Code Playgroud)

出现以下编译错误

Error:(22, 25) ambiguous implicit values:
 both method hnilComapped in object Comapped of type [F[_]]=> shapeless.ops.hlist.Comapped.Aux[shapeless.HNil,F,shapeless.HNil]
 and method hlistComapped in object Comapped of type [H, T <: shapeless.HList, F[_]](implicit mt: shapeless.ops.hlist.Comapped[T,F])shapeless.ops.hlist.Comapped.Aux[shapeless.::[F[H],T],F,shapeless.::[H,mt.Out]]
 match expected type shapeless.ops.hlist.Comapped.Aux[LN,Foo.this.Node,N]
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString)
                        ^
Error:(22, 25) could not find implicit value for parameter unwrap: shapeless.ops.hlist.Comapped.Aux[LN,Foo.this.Node,N]
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString)
                        ^
Error:(22, 25) not enough arguments for method foo: (implicit unwrap: shapeless.ops.hlist.Comapped.Aux[LN,Foo.this.Node,N], implicit tupToHlist: shapeless.Generic.Aux[(Foo.this.Node[Int], Foo.this.Node[String]),LN])Nothing.
Unspecified value parameters unwrap, tupToHlist.
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString)
                        ^
Run Code Online (Sandbox Code Playgroud)

zig*_*tar 1

根据我对 Lorand Szakacs 提到的问题的评论的阅读,我得出的结论是,隐式参数的顺序在当前版本2.11的 Scala 编译器中很重要。

这是因为参与讨论的开发人员似乎认为顺序很重要;他们没有明确说明。

我不知道语言规范提到了有关此主题的任何内容。