1

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

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]
4

1 回答 1

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是 a val,而不是 a def(即它是函数对象的实例,而不是方法)。对象实例必须具有特定类型。如果您想在此处使用泛型类型,则必须将其包装在具有泛型类型的类定义中,但即便如此,泛型类型也将被限制为为该类的每个特定实例指定/推断的类型。val

简而言之,如果要组合方法并保留类型参数,则需要手动组合它们并声明它def

def composed[A](list: List[A]): String = method2(method1(list))
于 2013-09-27T15:32:07.887 回答