2012-06-26 3 views
5

Auch .head funktioniert nicht.Warum kann ich nicht in einen HList indexieren, der durch Mapping über einen anderen HList erhalten wurde?

Welche Änderungen muss ich vornehmen, damit dies funktioniert?

import shapeless._ 
import HList._ 
import Nat._ 

scala> case class Foo[A](a: A) 
defined class Foo 

scala> case class Bar[A](f: Foo[A]) 
defined class Bar 

scala> val xs = Foo(23) :: Foo("blah") :: HNil 
xs: shapeless.::[Foo[Int],shapeless.::[Foo[java.lang.String],shapeless.HNil]] = Foo(23) :: Foo(blah) :: HNil 

scala> object mapper extends (Foo ~> Bar) { 
    | def apply[A](f: Foo[A]) = Bar(f) 
    | } 
defined module mapper 

scala> xs map mapper 
res13: mapper.Out = Bar(Foo(23)) :: Bar(Foo(blah)) :: HNil 

scala> res13.apply[_1] 
<console>:38: error: could not find implicit value for parameter at: shapeless.At[mapper.Out,shapeless.Nat._1] 
       res13.apply[_1] 
         ^

scala> res13.head 
<console>:38: error: could not find implicit value for parameter c: shapeless.IsHCons[mapper.Out] 
       res13.head 
        ^

Antwort

6

Works für mich genau wie geschrieben, zumindest mit den neuesten 2.10.0-snapshot,

import shapeless._ 
import HList._ 
import Nat._ 

scala> case class Foo[A](a: A) 
defined class Foo 

scala> case class Bar[A](f: Foo[A]) 
defined class Bar 

scala> val xs = Foo(23) :: Foo("blah") :: HNil 
xs: shapeless.::[Foo[Int],shapeless.::[Foo[String],shapeless.HNil]] = Foo(23) :: Foo(blah) :: HNil                          

scala> object mapper extends (Foo ~> Bar) { 
    | def apply[A](f: Foo[A]) = Bar(f)                                        
    | }                                                
defined module mapper                                             

scala> xs map mapper                                             
res0: shapeless.::[Bar[Int],shapeless.::[Bar[String],shapeless.HNil]] = Bar(Foo(23)) :: Bar(Foo(blah)) :: HNil                       

scala> res0[_1] 
res1: Bar[String] = Bar(Foo(blah))                                          

scala> res0.head                                              
res2: Bar[Int] = Bar(Foo(23)) 

Beachten Sie, dass der Typ für res0 oben geschlossen ist Bar[Int] :: Bar[String] :: HNil statt mapper.Out ... Ich vermute, dass dies ein Unterschied im Verhalten zwischen 2.9.x und 2.10.0-SNAPSHOT ist.

Wenn Sie mit 2.9.x stecken bleiben, dann sollten Sie in der Lage sein, das Problem zu umgehen, indem Sie Bar[Int] :: Bar[String] :: HNil explizit zu Ihrer res13 hinzufügen ... offensichtlich ist das mehr wortreich, aber c'est la vie.

Verwandte Themen