函数组合的类型不匹配

时间:2016-10-21 13:08:52

标签: scala

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

def identity[T](x: T): T = x
def composition[A, B, C](f: A => B, g: B => C)(x: A) = g(f(x))

我试图断言身份函数可以在两面都应用,结果相同:

assert(composition((x: Int) => x + 1, identity)(3) == composition(identity, (x: Int) => x + 1)(3))

但是,我收到了这些错误:

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));}

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));}

为什么会这样?

2 个答案:

答案 0 :(得分:8)

这是因为编译器难以正确推断类型,特别是推断A是什么。您可以通过将A作为第一个参数并将每个函数放在单独的参数列表中来帮助他:

def composition[A, B, C](x: A)(f: A => B)(g: B => C) = g(f(x))

现在这可以按预期工作:

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

或者,您可以显式指定type参数以帮助编译器推断出正确的类型:

println(composition((x: Int) => x + 1, identity[Int], 3) == 
        composition(identity[Int], (x: Int) => x + 1, 3))

答案 1 :(得分:5)

下面应该有效。请注意身份函数的类型参数。

docker create

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