2012-10-31 35 views
6

我有以下方法Scala是不推断适当的方法

def show[E: Writes, T: Writes](block: RequestWithUser[AnyContent] => Either[E, T]): Action[AnyContent] = { 
    withErr(block) 
} 

我使用这样从控制器:

def show(id: Long) = CrudAuthAction.show { request => 
    IdeaType.findByIdWithErr(id) 
} 

我想请求方法是可选的,所以我定义另一个签名为相同的方法:

def show[E: Writes, T: Writes](block: => Either[E, T]): Action[AnyContent] = { 
    withErr(request => block) 
} 

它工作正常,我可以省略请求参数

但是当我尝试做同样与此另一种方法

def list[T: Writes](block: RequestWithUser[AnyContent] => T): Action[AnyContent] = { 
    fromRequest(block) 
} 

def list[T: Writes](block: => T): Action[AnyContent] = { 
    fromRequest(request => block) 
} 

当我想用这样的:

def list = CrudAuthAction.list { request => 
    IdeaType.find(request.queryString) 
} 

它告诉我,请求缺少参数类型,以及我必须这样指定它:

def list = CrudAuthAction.list { request: RequestWithUser[AnyContent] => 

我没有看到与第一种情况有什么不同,但是缩放一个似乎无法推断正确的请求类型...

我看到的唯一区别是,在第一种情况下,块返回Either [E,T],但在第二种情况下返回只是一个通用的T ...

+2

需要极少重复性的例子。取决于IdeaType.find,CrudAuthAction等的定义 – themel

+1

@themel:我不认为有任何要求发布完整的例子,特别是如果问题得到了明确和详细解释,就像它在这里一样。 –

回答

5

问题是,在第二个例子中,编译器不知道选择哪个重载方法,因为T很可能是一个函数类型。由于Either显然不是一种功能,它在第一种情况下起作用。不幸的是

case class Foo[T](val v:T) 

,添加的隐式转换到美孚再次打破了东西,除非:

要解决这个问题,你可以在第二个方法改变为

def list[T: Writes](block: => Foo[T]): Action[AnyContent] = { 
    fromRequest(request => block.v) 
} 

随着美孚这样的定义您为Writes类型类中的每个类型创建隐式转换。

+0

让我看看我能不能跟着你。你的意思是在这种情况下,block:=> T,也可以匹配一个接受一个参数的函数,比如{request => ...},所以我应该给编译器提供更多的线索...... – opensas

+0

不,我的意思是对于所有的编译器都知道,T可能是一个函数类型。 –