首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从HMap类型创建HList

从HMap类型创建HList
EN

Stack Overflow用户
提问于 2016-07-04 08:45:11
回答 1查看 115关注 0票数 0

给定一个类型参数(即HList ),我希望创建一个HMap,其中包含HList类型的typeTags作为键,如下所示:

(不一定非得是typeTag,只是可以保存类型的东西)

代码语言:javascript
复制
def createMap[L <: HList](valueFunction:...):HMap = {
  //create an HMap with typeTags of HList elements as keys
  //values of HMap is created with passed 'valueFunction' which is a type parameterized function creating the value.
}

case class Person(..)
case class Address(..)

def valueFunction[T] = Map[Long, T]()

val hmap = createMap[Person :: Address :: HNil](valueFunction _)

val personValue:Map[Long, Person] = hmap(typeTag[Person])
  1. 如何实现createMap (签名、返回值和实现)?
  2. 如何指定有效的valueFunction?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-06 07:11:33

我试着做了一些反思。可能会将其中的一些转换成宏。

代码语言:javascript
复制
    import Repository._
    import shapeless.{HList, HMap, Id}

    import scala.collection.mutable
    import scala.reflect.api
    import scala.reflect.runtime.universe._

    trait Repository[L <: HList] {
      implicit val ltag: TypeTag[L]

      implicit object TLM extends (~??>[TypeTag, Long, mutable.Map])

      val repos: HMap[(~??>[TypeTag, Long, mutable.Map])#λ] = {
        val tts: List[TypeTag[_]] = ltag.tpe.dealias.typeArgs.dropRight(1).map(typeToTypeTag _)
        tts.tail.foldLeft(HMap[(~??>[TypeTag, Long, mutable.Map])#λ](getEntry(tts.head)))(_ + getEntry(_))
      }
    }

    object Repository {

      def getEntry[T](key: TypeTag[T]): (TypeTag[T], mutable.Map[Long, T]) = key -> mutable.Map[Long, T]()

      //copied and modified from shapeless ~?> in HMap
      class ~??>[K[_], K0, V[K0, _]] extends Serializable {
        class λ[K, V] extends Serializable
      }

      object ~??> extends NatTRel0 {
//not entirely sure if I need this method and/or the next one, but will keep it for now
        implicit def rel[K[_], K0, V[K0, _]]: ~??>[K, K0, V] = new (~??>[K, K0, V])

        implicit def idKeyWitness[K0, V[K0, _], T](implicit rel: ~??>[Id, K0, V]): rel.λ[T, V[K0, T]] = new rel.λ[Id[T], V[K0, T]]

        //this doesnt fit 3 type params, dont know how to port from ~?>
        //    implicit def idValueWitness[K[_], K0, T](implicit rel: ~??>[K, K0, Id]): rel.λ[K[T], T] = new rel.λ[K[T], Id[T]]
      }

      trait NatTRel0 {
        implicit def witness[K[_], K0, V[K0, _], T](implicit rel: ~??>[K, K0, V]): rel.λ[K[T], V[K0, T]] = new rel.λ[K[T], V[K0, T]]
      }

      def typeToTypeTag[T](tpe: Type)(implicit mirror: Mirror = runtimeMirror(getClass.getClassLoader)): TypeTag[T] =
        TypeTag(mirror, new api.TypeCreator {
          def apply[U <: api.Universe with Singleton](m: api.Mirror[U]) =
            if (m eq mirror) tpe.asInstanceOf[U#Type]
            else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
        })
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38180322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档