我刚刚意识到我的通用方法:
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]
答案 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
。但是,composed
是val
,而不是def
(即它是函数对象的实例 ,而不是方法)。对象实例必须具有特定类型。如果您想在此处使用泛型类型,那么您必须将此val
包装在具有泛型类型的类定义中,但即使这样,泛型类型也将限制为针对每个特定类型指定/推断的类型那个班的实例。
简而言之,如果你想组合方法并保留type参数,你需要手动编写它们并用def
声明它:
def composed[A](list: List[A]): String = method2(method1(list))