Scala警告:抽象类型模式Z未被选中,因为它是通过擦除消除的

时间:2014-09-23 19:36:11

标签: scala type-erasure

我已经查看了有关此主题的答案,但我还没有解决如何解决此代码段中的问题:

object MyObj {

  def validate[Z](json: JsValue)(implicit rds: Reads[Z]): Either[Error,Z] = {
    json.validate[Z].map{ 
      case r: Z => Right(r)  // Type Erasure here....
    }.recoverTotal{
      e => Left(JsonParsingError(JsError.toFlatJson(e).toString))
    }
  }

}

任何帮助?

1 个答案:

答案 0 :(得分:1)

我认为你要做的就是杀死那个错误就是删除类型归属: Z。如果Z首先为您提供validate,则您已经知道它将是JsSuccess。否则你最终会进入recoverTotal

我想你想要:

object MyObj {
  def validate[Z](json: JsValue)(implicit rds: Reads[Z]): Either[Error,Z] = {
    json.validate[Z].map(Right _).recoverTotal{ e => 
      Left(JsonParsingError(JsError.toFlatJson(e).toString))
    }
  }
}

虽然你真正想要的是:

implicit def readsEither[Z](implicit rds: Reads[Z]): Reads[Either[Error, Z]] = Reads { json =>
  rds.reads(json).map(Right(_)).recoverTotal { e => 
    JsSuccess(Left(JsonParsingError(JsError.toFlatJson(e).toString)))
  }
}

后一个例子很好,因为它定义了一个Reads,它很好地组合。

我没有测试任何这个,但事实并非如此,因为我没有JsonParsingError,但这或多或少会解决你的问题。

修改:鉴于您的代码已经需要隐式Reads[Z],您也可以尝试:

def jsonAsEither(json: JsValue)(implicit rds: Reads[Z]) =
  Json.fromJson(json).asEither.left.map( /* ... */ ).e