我已经定义了一个身份函数和一个组合函数:
def identity[T](x: T): T = x
def composition[A, B, C](f: A => B, g: B => C)(x: A) = g(f(x))
Run Code Online (Sandbox Code Playgroud)
我试图断言身份函数可以应用于两侧,结果相同:
assert(composition((x: Int) => x + 1, identity)(3) == composition(identity, (x: Int) => x + 1)(3))
Run Code Online (Sandbox Code Playgroud)
但是,我收到这些错误:
Error:(7, 40) type mismatch;
found : Nothing => Nothing
required: Int => Nothing
assert(composition((x: Int) => x + 1, identity)(3) == composition(identity, (x: Int) => x + 1)(3));}
Run Code Online (Sandbox Code Playgroud)
和:
Error:(7, 68) type mismatch;
found : Nothing => Nothing
required: A => Nothing
assert(composition((x: Int) => x + 1, identity)(3) == composition(identity, (x: Int) => x + 1)(3));}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
情况就是这样,因为编译器很难正确地推断出类型,特别是推断出什么A是类型.您可以通过将A第一个参数和每个函数放在单独的参数列表中来帮助他:
def composition[A, B, C](x: A)(f: A => B)(g: B => C) = g(f(x))
Run Code Online (Sandbox Code Playgroud)
现在这可以按预期工作:
scala> :pa
// Entering paste mode (ctrl-D to finish)
def identity[T](x: T): T = x
def composition[A, B, C](x: A)(f: A => B)(g: B => C) = g(f(x))
// Exiting paste mode, now interpreting.
identity: [T](x: T)T
composition: [A, B, C](x: A)(f: A => B)(g: B => C)C
scala> println(composition(3)((x: Int) => x + 1)(identity) == composition(3)(identity)((x: Int) => x + 1))
true
Run Code Online (Sandbox Code Playgroud)
或者,您可以显式指定type参数以帮助编译器推断出正确的类型:
println(composition((x: Int) => x + 1, identity[Int], 3) ==
composition(identity[Int], (x: Int) => x + 1, 3))
Run Code Online (Sandbox Code Playgroud)
下面应该工作.请注意标识函数的类型参数.
assert(composition((x: Int) => x + 1, identity[Int])(3) == composition(identity[Int], (x: Int) => x + 1)(3))
Run Code Online (Sandbox Code Playgroud)
由于您尚未为标识函数指定类型参数,因此它将变为Nothing,并且与方法的类型签名不匹配.