Учитывая некоторый методИмеет ли порядок неявных параметров в Scala?
def f[A,B](p: A)(implicit a: X[A,B], b: Y[B])
ли порядок a
перед тем b
в неявных параметрах списка вещества для вывода типа?
Я думал, что только размещение параметров в разных списках параметров имеет значение, например. тип информации передается только через списки параметров слева направо.
Я спрашиваю, потому что заметил, что изменение порядка неявных параметров в одном неявном списке создало программу компиляции.
Реальный пример
Следующий код использует:
- бесформенный 2.1.0
- Scala 2.11.5
Вот простой файл SBT сборки, чтобы помочь вместе с составление примеров:
scalaVersion := "2.11.5"
libraryDependencies += "com.chuusai" %% "shapeless" % "2.1.0"
scalaSource in Compile := baseDirectory.value
На примере. Этот код компилируется:
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)
}
}
и этот код не
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)
}
}
со следующей компиляции ошибки
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)
^
Порядок не должен иметь значения, по крайней мере, в изоляции. Однако изменение порядка импликации определенно меняет сигнатуру метода, поэтому он изменяет тип определяемого им класса/признака. В любом случае вы должны обязательно опубликовать фрагмент кода, демонстрирующий, как изменение порядка изменяет результат компиляции, в противном случае Трудно обсуждать эту проблему. –
@ RégisJean-Gilles Я добавил несколько небольшой пример. – ziggystar