Scala隐式转换器

Scala隐式转换器,scala,implicit-conversion,Scala,Implicit Conversion,我试图找出如何为特定类型创建隐式转换器。在我的例子中,这将是一个Set[IdParam[T]]到Set[IdTag[T]],其中 import shapeless.tag.@@ case class IdParam[T](value: IdTag[T]) type IdTag[T] = Id @@ T class Id(val value: Long) object Id { def tag[T](l: Long) = shapeless.tag[T][Id](new Id(l))

我试图找出如何为特定类型创建隐式转换器。在我的例子中,这将是一个
Set[IdParam[T]]
Set[IdTag[T]]
,其中

import shapeless.tag.@@

case class IdParam[T](value: IdTag[T])
type IdTag[T] = Id @@ T

class Id(val value: Long)
object Id {
  def tag[T](l: Long) = shapeless.tag[T][Id](new Id(l))

  def value[T](l: Long) = Id.tag[T](l)
}
我写了一个简单的

implicit def toIds[T](idParams: Set[IdParam[T]]): Set[IdTag[T]] = idParams.map(_.value)
哪个好用。但我现在的主要问题是,是否有一种方法可以创建一个包含Seq和Set的隐式转换器。在等级制度上,这将意味着一个可移植的。 尝试了以下方法

implicit def toIds[I <: Iterable[IdParam[T]], T](idParams: I): Iterable[IdTag[T]] = idParams.map(_.value)
编辑 该隐式转换器应在控制器端点中使用

GET     /campaigns @dummy.Campaigns.all(profileId: Set[IdParam[ProfileIdTag]] ?= Set.empty)
我有一个QueryStringBindable,它将作为字符串检索的查询参数转换为
集[IdParam[a]]

object IdQueryStringBinder {
  implicit def idParamQueryStringBinder[A](implicit stringBinder: QueryStringBindable[String]) =
new QueryStringBindable[IdParam[A]] {

    def bind(key: String, params: Map[String, Seq[String]]): Option[Either[String, IdParam[A]]] =
      for {
        idEither <- stringBinder.bind(key, params)
      } yield {
        idEither match {
          case Right(idString) =>
            IdBinder.parseIdString(idString)
          case Left(_) => Left("Unable to bind an Id")
        }
      }

    override def unbind(key: String, id: IdParam[A]): String =
      stringBinder.unbind(key, id.value.toString)
  }

  implicit def idsParamQueryStringBinder[A](implicit stringBinder: QueryStringBindable[String]) =
    new QueryStringBindable[Set[IdParam[A]]] {
      override def bind(key: String, params: Map[String, Seq[String]]): Option[Either[String, Set[IdParam[A]]]] = {
        stringBinder.bind(key, params).map(_.right.flatMap(parse))
      }

      private def parse(idsString: String): Either[String, Set[IdParam[A]]] = {
        val (wrongIds, correctIds) = idsString.split(",")
          .map(id => IdBinder.parseIdString[A](id))
          .partition(_.isLeft)
        if (wrongIds.nonEmpty) {
          Left(s"Could not bind the following Ids: ${wrongIds.map(_.left.get).mkString(",")}")
        } else {
          Right(correctIds.map(_.right.get).toSet)
        }
      }

      override def unbind(key: String, ids: Set[IdParam[A]]): String =
        stringBinder.unbind(key, ids.map(_.value.toString).mkString(","))
    }
}
第一个端点工作,它使用定义的
idParamQueryStringBinder
和以下隐式转换器

implicit def toId[T](idParam: IdParam[T]): IdTag[T] = idParam.value

您一定犯了一些编码错误,因为它对我来说非常好:


下次粘贴导致问题的完整代码,而不仅仅是小部分。

添加导致错误的代码这是引发错误的原因:
[error]GET/activities@dummy.activities.all(profileId:Set[IdParam[ProfileIdTag]]?=Set.empty)
感谢您对此进行调查。我已经添加了代码的更多细节。@@是从无形状库中获取的,而不是scalaz。对不起,我以前没提过。
class Campaigns extends play.api.mvc.Controller {
  def allByProfileId(profile: ProfileId) = ...
  def all(profileIds: Set[ProfileId]) = ...
}
implicit def toId[T](idParam: IdParam[T]): IdTag[T] = idParam.value