具有此代码
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")) }使用
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]有没有办法确保scala,在这种情况下,我想将变量T键入为Project,然后选择projectJSON函数对其进行解析?或者,如果我做错了,那怎么做才正确呢?
解决方案编译器正在尝试自动推断类型T,该类型必须是可以从String开始生成的类型(或多或少,但此处不重要)
不幸的是,它无法成功,因为您要提供从String到Project和Workspace的多个隐式转换.一种简单的解决方案是明确指出您要生成的类型:
parseEnt[Project](parse("some text"))此模式在序列化类型类中相当普遍,在该类中,您将多个特定类型映射到通用类型(在本例中为String).
Having this code
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")) }Which fails to compile on parseEnt(parse("some text")) with
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]Is there a way to assure scala, that in this case I want type variable T to be a Project and choose projectJSON function to parse it? Or if I'm doing it wrong, then how do it in right way?
解决方案The compiler is trying to automatically infer the type T, which must be something that it can be produced starting from a String (more or less, but details an unimportant here)
Unfortunately it can't succeed, since you're providing multiple implicit conversions going from String to Project and Workspace. The simple solution is to explicitly indicate the type you're trying to produce:
parseEnt[Project](parse("some text"))This pattern is fairly common with serialization type classes, where you are mapping multiple specific types to a generic one (String in this case).
更多推荐
在scala中进行隐式转换遇到麻烦
发布评论