scala - 函数组合的类型不匹配

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

为什么会这样?

最佳答案

这是因为编译器很难正确推断类型,特别是推断 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

或者,您可以显式指定类型参数以帮助编译器推断正确的类型:
println(composition((x: Int) => x + 1, identity[Int], 3) == 
        composition(identity[Int], (x: Int) => x + 1, 3))

关于scala - 函数组合的类型不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40177507/

相关文章:

java - 如何在 Akka Actor 之间传递远程引用?

scala - 给定集合 A 和 B,是否有标准库函数来生成 3-ple(A - B、交集、B - A)?

scala - Spark scala RDD遍历

scala - 我很想知道 IDEA 的这个烦人的功能是什么 --- 这样我就可以将其关闭

scala - scala 字节码中不必要的加载和存储指令

scala - 找不到用于排序的 Traverse Seq[ValidationNel[String, MyCaseClass]] => ValidationNel[String, Seq[MyCaseClass]]

scala - Scala 和 Groovy 之间的主要区别是什么?

generics - 在 Scala 中创建参数图类型

Scala:检查2个变量是否属于同一类型

scala - 绕过模式匹配中的类型删除