2012-06-26 8 views
5

Incluso .head no funciona.¿Por qué no puedo indexar en una HList obtenida mapeando sobre otra HList?

¿Qué cambios debo hacer para que esto funcione?

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 
        ^

Respuesta

6

me funciona exactamente como está escrito, al menos con la última 2.10.0-INSTANTÁNEA,

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)) 

en cuenta que el tipo infiere de lo anterior es res0Bar[Int] :: Bar[String] :: HNil en lugar de mapper.Out ... Sospecho que esta es una diferencia de comportamiento entre 2.9.x y 2.10.0-SNAPSHOT.

Si tiene problemas con 2.9.x entonces creo que debería poder evitar el problema atribuyendo Bar[Int] :: Bar[String] :: HNil a su res13 explícitamente ... obviamente eso es más detallado, pero c'est la vie.

Cuestiones relacionadas