输入容器类型的类

时间:2017-12-02 20:58:15

标签: scala typeclass

我想构建一个没有任何依赖关系的接口,只有scala库

让我们想象这就是我想要的:

iface.jar

trait jsonIface[JsValue] {

  def turnJsonIntoClass[T](t: JsValue)

}

如您所见,它不包含任何导入。

让我们去实施:

iface_implementation1.jar

import play.api.libs.json._

trait myPlayJsonImpl extends jsonIface[JsValue] {

      def turnJsonIntoClass[T](t: JsValue) { t.as[T] }

}

但这不会编译,因为[T]需要隐式Reads [T]

所以我改写了我的iface:

trait jsonIface[JsValue] {

  type metaInfo[T]

  def turnJsonIntoClass[T](t: JsValue)(implicit meta: metaInfo[T])

}

播放json impl看起来像这样:

import play.api.libs.json._

trait myPlayJsonImpl extends jsonIface[JsValue] {

  type conv[M] = Reads[M]

  def turnJsonIntoClass[T](t: JsValue)(implicit reads: Reads[T]) { t.as[T] }    

}

和json4s看起来像这样:

import org.json4s.JsonAST._

trait json4sImpl extends jsonIface[JValue] {

  type conv[M] = Manifest[M]

  def turnJsonIntoClass[T](t: JsValue)(implicit reads: Manifest[T]) { t.extract[T] }    

}

这编译但看起来很麻烦

1 个答案:

答案 0 :(得分:0)

通常,当您开始使用类型类特征时,您将继续这样做,而不是使用OOP特征:

import org.json4s.Formats
import org.json4s.JsonAST.JValue
import play.api.libs.json.{JsValue, Reads}

trait jsonIface[JsValue, T] {
  def turnJsonIntoClass(t: JsValue): T
}

object jsonIface {
  implicit def json4sImpl[T](implicit formats: Formats, manifest: Manifest[T]): jsonIface[JValue, T] = new jsonIface[JValue, T] {
    def turnJsonIntoClass(t: JValue): T = t.extract[T]
  }

  implicit def myPlayJsonImpl[T](implicit reads: Reads[T]): jsonIface[JsValue, T] = new jsonIface[JsValue, T] {
    def turnJsonIntoClass(t: JsValue): T = t.as[T]
  }
}

object jsonIface {
  implicit def json4sImpl[T](implicit formats: Formats, manifest: Manifest[T]): jsonIface[JValue, T] = (t: JValue) => t.extract[T]

  implicit def myPlayJsonImpl[T](implicit reads: Reads[T]): jsonIface[JsValue, T] = (t: JsValue) => t.as[T]
}