2014-07-19 211 views
0

有了这个代码经与隐式转换的麻烦斯卡拉

case class Workspace(ident: Long, name: String) 
case class Project(ident: Long, name: String) 

implicit def workspaceJSON: JSONR[Workspace] = new JSONR[Workspace] { 
    def read(json: JValue) = 
    Workspace.applyJSON(field[Long]("id"), field[String]("name"))(json) 
} 

implicit def projectJSON: JSONR[Project] = new JSONR[Project] { 
    def read(json: JValue) = 
    Project.applyJSON(field[Long]("id"), field[String]("name"))(json) 
} 

def parseEnt[T: JSONR](json: JValue): Either[String, T] = 
    fromJSON[T](json).toEither.left.map{ _.toString } 

def fetchProjects(ws: Workspace): Either[String, Project] = { 
    parseEnt(parse("some text")) 
} 

从而未能在parseEnt(parse("some text"))编译

ambiguous implicit values: both method taskJSON in class Fetcher of type => 
Fetcher.this.JSONR[types.Task] and method workspaceJSON in class Fetcher of type => 
Fetcher.this.JSONR[Fetcher.this.Workspace] match expected type Fetcher.this.JSONR[T] 

有没有一种方法,以确保阶,在这种情况下,我想类型变量T将成为Project并选择projectJSON函数来解析它?或者如果我做错了,那么它是如何以正确的方式呢?

+0

如果您明确说出您期望解析的内容,那么该怎么办? parseEnt [Project](解析(“一些文本”)) – johanandren

+0

谢谢你,帮助。 – cvb

回答

0

编译器正在尝试自动推断类型T,它必须是东西,它可以从一个String开始生产(多跌少,但具体细节在这里不重要)

不幸的是,能不能成功,因为您提供了从StringProjectWorkspace的多个隐式转换。简单的解决方案是明确地指出你想生成类型:

parseEnt[Project](parse("some text")) 

这种模式是相当普遍的系列化类型类,你在哪里映射多个特定类型(在这种情况下String)的通用一个。

+0

我知道编译器对于使用哪个实例是模糊的,但我觉得它不能从类型的函数'fetchProjects'中输入类型,我认为这很清楚,在这种情况下'T'应该是'Project '。似乎我必须阅读更多关于类型推断和scala中的暗示。 – cvb