2016-04-09 27 views
2

ile eşleştirmeye dönüştürürüm, shapeless ile çalışmaya başladım ve konseptin kanıtı olarak, Hlist'i Map'e dönüştürmek için bir işlev tanımladım, fakat bir şeyler yanlış gitti, lütfen bana yardımcı olabilir misiniz?HList'i Shapless

object bar extends Poly1 { 
    implicit def caseTuple[T, U](implicit st: Case.Aux[T, Map[String, Any]], su: Case.Aux[U, Map[String, Any]]) = 
    at[(T, U)](t => { 
    Map(s"${t._1}" -> t._2) 
    }) 
} 

object foo extends Poly2 { 
implicit def default[T](implicit st: bar.Case.Aux[T, Map[String, Any]]) = 
    at[Map[String, Any], T] { (acc, t) => 
    acC++ bar(t) 
    } 
} 

val h = ("k1", 1) :: ("k2", "foo") :: HNil 
println(h.foldLeft(Map.empty[String, Any])(foo)) 

Ama hata var: could not find implicit value for parameter folder: shapeless.ops.hlist.LeftFolder[shapeless.::[(String, Int),shapeless.::[(String, String),shapeless.HNil]],scala.collection.immutable.Map[String,Any],Main.foo.type] [error] println(h.foldLeft(Map.empty[String, Any])(foo))

cevap

1
  1. Eğer değer türü umurumda değil gibi, değer türü için özel polimorfik işlevini gerekmez.

  2. sadece .toString dayanarak ediyorsanız, aşağıdaki örnekteki gibi tekrar yazılabilir böylece Poly1 gerekmez:

object foo1 extends Poly2 { 
    implicit def default[K, V] = 
    at[Map[String, Any], (K, V)] { case (acc, (k, v)) => 
     acc + (k.toString -> v) 
    } 
} 

val h = ("k1", 1) :: ("k2", "foo") :: (true, "TRUE") :: HNil 
println(h.foldLeft(Map.empty[String, Any])(foo1)) 
// Map(k1 -> 1, k2 -> foo, true -> TRUE) 
  1. Anahtar konumunda birden fazla tür varsa, bunları dizeye dönüştürmeniz gerekir. Poly1 veya scalaz.Show veya cats.Show gibi herhangi bir yazım hatası olabilir ve A => String sağlar.
object bar2 extends Poly1 { 
    implicit val stringCase = at[String](identity) 
    implicit val symbolCase = at[Symbol](_.name) 
    implicit def integralCase[A: Integral] = at[A](_.toString) 
    implicit def fractionalCase[A: Fractional] = at[A](_ formatted "%.2f") 
} 

object foo2 extends Poly2 { 
    implicit def default[K, V](implicit bk: bar2.Case.Aux[K, String]) = 
    at[Map[String, Any], (K, V)] { case (acc, (k, v)) => 
     acc + (bk(k) -> v) 
    } 
} 

val h2 = ("k1", 1) :: ("k2", "foo") :: ('k3, true) :: (12.3456, 'frac) :: HNil 
println(h2.foldLeft(Map.empty[String, Any])(foo2)) 
// Map(k1 -> 1, k2 -> foo, k3 -> true, 12.35 -> 'frac) 

yerine Any başka anahtar türü olması aynısını yapabilirsiniz.