在不丢失通用参数的情况下调整通用方法/函数

时间:2013-09-27 14:59:48

标签: scala generics function-pointers

我刚刚意识到我的通用方法:

def method[A](list: List[A]): A = { ... }

将导致非泛型函数类型

val methodFun = method _
-> methodFun : (scala.List[Nothing]) => Nothing

currying 时,而不是保持其泛型类​​型。是否有可能保留泛型类型信息?我发现我可以通过设置

来定义一些显式类型,例如String
val methodFun = method[String] _
-> methodFun : (scala.List[String]) => String

但这不是我想要的。我目前倾向于使用原始类型来避免这个问题(一旦我知道如何)或者是否有更好的解决方案?

感谢您的帮助!

PS:为什么我想这样做:

def method1[A](list: List[A]): A = { ... }
def method2[A](element: A): Int = { ... }
// This will not cause a compiler error as stated before
// but this will result in (List[Nothing]) => Int
// but I want a (List[A]) => Int
val composedFun = method1 _ andThen method2
// The next line is possible
// but it gives me a (List[String]) => Int
val composedFunNonGeneric = method1[String] _ andThen method2[String]

1 个答案:

答案 0 :(得分:4)

让我们来看看你的例子:

def method1[A](list: List[A]): A = { ... }
def method2[A](element: A): String = { ... }
// The next line will cause a compiler error
val composed = method1 _ andThen method2

首先,这不会给我一个编译器错误,而是你提到的太具体的类型(List[Nothing]=>String)

如果您想了解为什么这不起作用,请以这种方式思考:您期望composed的类型是什么?我想你想要这样的事情List[A]=>String。但是,composedval,而不是def(即它是函数对象的实例 ,而不是方法)。对象实例必须具有特定类型。如果您想在此处使用泛型类型,那么您必须将此val包装在具有泛型类型的类定义中,但即使这样,泛型类型也将限制为针对每个特定类型指定/推断的类型那个班的实例。

简而言之,如果你想组合方法并保留type参数,你需要手动编写它们并用def声明它:

def composed[A](list: List[A]): String = method2(method1(list))