我有一个函数,它将一个类型化的排序函数作为参数,我希望这个sort函数有一个默认参数:
def foo[T](sort: MyObject => T = _.position)(implicit o: Ordering[T])
MyObject.position
会返回Int
。
可以理解,我收到了这个错误:
Expression of type (MyObject) => Int doesn't conform to expected type (MyObject) => T
好的,但是我希望编译器能够确定在默认情况下T
是Int
并检查Ordering[Int]
范围内implicit
是否可用。
如何帮助编译器解决此问题?
答案 0 :(得分:2)
您可以使用带有和不带参数的重载函数:
def foo(): FooResult = foo(_.position)
def foo[T](sort: MyObject => T)(implicit o: Ordering[T]): FooResult = ???
我可以通过一种方式思考,如何使用非重载函数(以及一些样板)来实现它。
您可以使用一个特殊参数,它包含sort
函数,foo
的排序甚至实现,并提供从适当函数到此参数的隐式转换。这基本上是Magnet pattern的应用。
sealed trait Magnet {
type T
val sort: MyObject => T
implicit val o: Ordering[T]
def fooImpl = ???
}
object Magnet {
implicit def fromSort[T0](sortArg: MyObject => T0)(implicit ordArg: Ordering[T0]): Magnet =
new Magnet {
type T = T0
val sort = sortArg
val o = ordArg
}
}
def foo(sort: Magnet = (_: MyObject).position) = sort.fooImpl
一个缺点是,这会丢失参数的预期类型,因此您必须指定sort
函数的参数类型。
您的案例的可用性值得怀疑,但它仍然是一个有趣的解决方案,并且可能在其他情况下有用。