2016-07-04 7 views
0

からHMAPを作成します。がHListあるタイプパラメータ、私はこのように、キーとしてHListの種類のtypeTagsでHMAPを作成したいを考えるHListタイプ

(typeTagである必要はありません、タイプを保持できるだけで何か)

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(署名、戻り値と implementaionを実装することができますか)?
  2. 有効なvalueFunctionを指定するにはどうすればよいですか?
+0

、私は、少なくとも各要素のいくつかのタイプの情報を抽出するための管理: typeTag [L] .tpe.dealias.typeArgs.dropRight(1) は今からHMAPを作成しようこの。 – eirirlar

答えて

0

私はこれを少しでも反映することができました。おそらくこれをマクロに変換する必要があります。 HListためtypeTagを使用して

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.") 
     }) 
    } 
関連する問題