当一个是返回值时如何推断类型?

时间:2013-10-13 01:08:31

标签: scala

我正在尝试定义一个在其参数和返回类型中都是通用的方法。基本上是为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 参数推断,因此用户只需在调用函数时指定返回类型。

2 个答案:

答案 0 :(得分:2)

我不太了解Scala的许多细节,但在Haskell中,能力是通过名为“Functional dependencies”的编译器选项启用的,其中你有一个带有两个类型变量的类型类,其中一个可以从另一个派生 - 见http://www.haskell.org/ghc/docs/6.6/html/users_guide/type-extensions.html第7.4.3节。显然你不能只使用这个功能,因为它是用不同的语言,但知道它的名称应该可以帮助你找到解决方案。例如,Functional dependencies in Scala看起来很好;虽然我再也不知道Scala能阅读那篇文章,然后告诉你如何回答你原来的JSON问题。

答案 1 :(得分:1)

根据@ amalloy的回答以及他提供的链接,您尝试实现的Scala等价物将如下所示:

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"))

这给出了输出:

result: B = B(456)