2017-10-06 89 views
0

我想這和它的作品可供選擇:LabelledGenerid.Aux隱含不使用函數體中的泛型類型時

` 
    case class Foo(name: String)

class Morphic(map: Map[String, Any]) { def add(k: String, v: Any) = { new Morphic((map + (k -> v))) } def to[T](): T = { def toClass[A]: ToCase[A] = new ToCase[A] // This is class to convert from Map to case class val res = toClass[Foo].from(map).get // <-- problem is here - cannot use T res.asInstanceOf[T] } } object testApp extends App { var m = new Morphic(Map[String, Any]()) var m1 = m.add("name", "john") println(m1.to[Foo]) }

我應該在val res = toClass[T].from(map).get使用的T,而不是富,但不編譯說隱缺少

toClass[T].from從地圖

創建一個給定類型的案件類的我如何作出這樣的隱式的(可能還有其他人在其上。從依賴)能夠使用的功能?

我試圖def to[T, H <: HList]()(implicit gen: LabelledGeneric.Aux[A, H]) = ...但後來我需要指定兩種類型的調用。要的時候,我無法弄清楚如何指定用於h

感謝

+0

寫下你的'ToCase'。 –

+0

如果我理解正確,'toClass [Foo] .from(map)'是類型'Foo'。 'toClass [Foo] .from(map).get'中的'.get'來自哪裏? 'Foo'中有'.get'嗎? –

+0

啊,也許它不是'Foo',而是'Option [Foo]'。 –

回答

1

你可以改變一個MapHList和那麼HListT

import shapeless.{::, HList, HNil, LabelledGeneric, Witness} 
import shapeless.labelled._ 

case class Foo(name: String) 

trait MapToHList[L <: HList] { 
    def apply(map: Map[String, Any]): Option[L] 
} 
object MapToHList { 
    implicit object hNilMapToHList extends MapToHList[HNil] { 
    override def apply(map: Map[String, Any]): Option[HNil] = Some(HNil) 
    } 

    implicit def hConsMapToHList[K <: Symbol, V, T <: HList](implicit 
                  mapToHList: MapToHList[T], 
                  witness: Witness.Aux[K] 
                 ): MapToHList[FieldType[K, V] :: T] = 
    new MapToHList[FieldType[K, V] :: T] { 
     override def apply(map: Map[String, Any]): Option[FieldType[K, V] :: T] = { 
     val str = witness.value.toString.tail 
     for { 
      v <- map.get(str) 
      t <- mapToHList(map) 
     } yield field[K](v.asInstanceOf[V]) :: t 
     } 
    } 
} 

trait ToCase[A] { 
    def from(map: Map[String, Any]): Option[A] 
} 
object ToCase { 
    implicit def mkToCase[A, L <: HList](implicit 
             gen: LabelledGeneric.Aux[A, L], 
             mapToHList: MapToHList[L] 
            ): ToCase[A] = 
    new ToCase[A] { 
     override def from(map: Map[String, Any]): Option[A] = mapToHList(map).map(gen.from) 
    } 
} 


class Morphic(map: Map[String, Any]) { 

    def add(k: String, v: Any) = { 
    new Morphic((map + (k -> v))) 
    } 

    def to[T](implicit toCase: ToCase[T]): T = toCase.from(map).get 

} 

object testApp extends App { 
    var m = new Morphic(Map[String, Any]()) 
    var m1 = m.add("name", "john") 
    println(m1.to[Foo]) // Foo(john) 
} 

我試過 def to[T, H <: HList]()(implicit gen: LabelledGeneric.Aux[A, H]) ... 後來我需要調用。要 時指定兩種類型,我無法弄清楚如何指定用於h

你可以把它作爲m1.to[Foo, FieldType[Witness.`'name`.T, String] :: HNil]()m1.to[Foo, Record.`'name -> String`.T]()

+0

這很完美,謝謝。我的.from代碼和你的類似,但是缺少的是整個隱式包裝器。我仍然不完全知道這是如何工作的 - 意味着我對整個隱含事物的理解很差,我現在要確保我完全瞭解它:) – r3stle55

+0

@ r3stle55祝你好運。如果你對答案感到滿意,你可以接受它。 –

相關問題