Scala 在不丢失泛型参数的情况下转换泛型方法/函数

Scala 在不丢失泛型参数的情况下转换泛型方法/函数,scala,generics,function-pointers,Scala,Generics,Function Pointers,我刚刚意识到我的通用方法: def method[A](list: List[A]): A = { ... } 将导致非泛型函数类型 val methodFun = method _ -> methodFun : (scala.List[Nothing]) => Nothing 在对其进行curry时,而不是保留其泛型类型。是否有可能保留泛型类型信息?我发现我可以通过设置 val methodFun = method[String] _ -> methodFun : (sc

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

def method[A](list: List[A]): A = { ... }
将导致非泛型函数类型

val methodFun = method _
-> methodFun : (scala.List[Nothing]) => Nothing
在对其进行curry时,而不是保留其泛型类型。是否有可能保留泛型类型信息?我发现我可以通过设置

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]

让我们看一下您的示例:

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)

如果您想了解为什么这样做不起作用,请这样想:您期望的
组合类型是什么?我想您需要这样的
List[A]=>String
。但是,
composited
val
,而不是
def
(即,它是函数对象的实例,而不是方法)。对象实例必须具有特定类型。如果您想在这里使用泛型类型,那么您必须使用泛型类型将此
val
包装在类定义中,但即使这样,泛型类型也将被限制为该类的每个特定实例指定/推断的类型

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

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

让我们看一下您的示例:

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)

如果您想了解为什么这样做不起作用,请这样想:您期望的
组合类型是什么?我想您需要这样的
List[A]=>String
。但是,
composited
val
,而不是
def
(即,它是函数对象的实例,而不是方法)。对象实例必须具有特定类型。如果您想在这里使用泛型类型,那么您必须使用泛型类型将此
val
包装在类定义中,但即使这样,泛型类型也将被限制为该类的每个特定实例指定/推断的类型

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

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

它在书面上没有意义,但总的来说,它是有意义的。要么是因为有多个参数,要么是因为我想组合函数。忽略我的第一条评论:这不是陈词滥调,而是扩展。;)我看到了它的意义。它不像书面上那样有意义,但总的来说,它是有意义的。要么是因为有多个参数,要么是因为我想组合函数。忽略我的第一条评论:这不是陈词滥调,而是扩展。;)我看到了它的意义。