2

我正在尝试定义一个在其参数和返回类型中都是通用的方法。基本上是为案例类的 JSON 序列化创建一个辅助函数。

所以我想写这样的伪代码:

def post[Request,Response](data:Request) : Response = ???

case class A(i:String)
case class B(j:Int)

val result = post[A,B]("input")

在这种情况下(假设没有错误)结果属于 B 类。

编译器无法推断返回值是可以理解的,但我希望它能够推断出 Request 类型。换句话说,我想写一些类似的东西

val result = post[B]("input")

其中 A 的类型是由data参数推断出来的,所以用户只需要在调用函数时指定返回类型即可。

4

2 回答 2

2

我具体不知道 Scala 的很多细节,但是在 Haskell 中,这种能力是由一个名为“功能依赖项”的编译器选项启用的,由此你有一个具有两个类型变量的类型类,其中一个可以从另一个派生 - 请参阅部分http://www.haskell.org/ghc/docs/6.6/html/users_guide/type-extensions.html的 7.4.3 。显然,您不能只使用此功能,因为它使用不同的语言,但是知道它的名称应该可以帮助您找到解决方案。例如,Scala 中的函数依赖似乎是一个不错的猜测;不过,我对 Scala 的了解还不够,无法阅读那篇文章,然后准确地告诉您如何回答您原来的 JSON 问题。

于 2013-10-13T01:22:42.123 回答
1

Following on from @amalloy's answer, and the link he provides, the Scala equivalent for what you are trying to achieve would be something like the following:

trait ReqResp[Request,Response] {
  def apply(req: Request): Response
}

def post[Request,Response](data:Request)(implicit rr: ReqResp[Request,Response]): Response = rr(data)

case class A(i:String)
case class B(j:Int)

implicit object reqRespAB extends ReqResp[A,B] {
  def apply(a: A) = B(a.i.toInt)
}

val result = post(A("456"))

This gives the output:

result: B = B(456)
于 2013-10-13T01:51:15.043 回答