Scala如何将多参数函数作为另一函数的泛型类型使用?
问题原因
你写的foo[T]本身就是接收单参数函数的,类型是T => Double。你指定T为(Double, Double)的时候,Scala自然会把它当成二元组类型,这时候传进去的函数是「拿单个二元组当入参、返回Double」的函数,返回值类型是((Double, Double)) => Double,和你给baz声明的返回值(Double, Double) => Double(两个入参的函数)根本不是一个类型,所以编译过不了。
解决方案
方案1:改动最小,用untupled做类型转换
Scala标准库给接收元组的单参数函数提供了内置的untupled方法,可以直接转成对应参数数量的多参数函数,不需要改原有foo的定义:
object Test { def bar: String => Double = { foo[String](_.toDouble) } def baz: (Double, Double) => Double = { foo[(Double, Double)] { case (d1, d2) => d1 + d2 }.untupled // 只需要加这一行做转换即可 } def foo[T](f: T => Double): T => Double = { f } }
方案2:重载foo原生支持多参数函数
如果想用法更统一,不需要每次手动转换,可以重载对应参数数量的foo方法,比如双参数版本:
object Test { def bar: String => Double = { foo[String](_.toDouble) } def baz: (Double, Double) => Double = { // 甚至不用显式写类型参数,Scala能自动推导 foo(_ + _) } // 保留原有单参数版本 def foo[T](f: T => Double): T => Double = f // 新增双参数重载 def foo[T1, T2](f: (T1, T2) => Double): (T1, T2) => Double = f }
如果需要支持三参数、四参数等更多参数数量,按照同样规则重载对应参数数量的foo即可。
内容的提问来源于stack exchange,提问作者worldwideop
相关产品推荐
相关产品推荐

