函数组合的类型不匹配

oct*_*ian 4 scala

我已经定义了一个身份函数和一个组合函数:

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)

为什么会这样?

Yuv*_*kov 8

情况就是这样,因为编译器很难正确地推断出类型,特别是推断出什么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)

  • @Samar因为类型推断仅在*参数列表之间流动*,而不是*在*它们之间. (2认同)

Jeg*_*gan 5

下面应该工作.请注意标识函数的类型参数.

assert(composition((x: Int) => x + 1, identity[Int])(3) == composition(identity[Int], (x: Int) => x + 1)(3))
Run Code Online (Sandbox Code Playgroud)

由于您尚未为标识函数指定类型参数,因此它将变为Nothing,并且与方法的类型签名不匹配.