En forma sin forma, tenga dos listas de modo que una contenga clases de tipo de la otra
Pregunta
En forma sin forma, estoy intentando escribir una función que requiera dos HList. l1
y l2
de longitud arbitraria que presentan las siguientes propiedades:
- Longitud de
l1
yl2
son lo mismo. l2
contiene los tipos exactos del1
, envuelto en un constructor de tipo externo constante.
Así que si l1
era
1 :: 1.2 :: "hello" :: HNil`
l2
podría ser
Ordering[Int] :: Ordering[Double] :: Ordering[String] :: HNil
Usando UnaryTCConstraint
y LengthAux
me permite restringir las longitudes y requerir un constructor externo estático para l2
, sin embargo lograr que se ajusten se ha convertido en un problema.
¿Alguna idea sobre cómo podría hacerlo?
Solución
Mapped
proporciona precisamente esta restricción sin la necesidad adicional de Length
.De la documentación:
Clase de tipo que atestigua que el resultado de envolver cada elemento de
HList
L
en constructor de tiposF
esOut
.
Así es como se ve en 1.2.4:
import shapeless._
def foo[L1 <: HList, L2 <: HList](l1: L1, l2: L2)(implicit
ev: MappedAux[L1, Ordering, L2]
) = ()
val l1 = 1 :: 1.2 :: "hello" :: HNil
val l2 = Ordering[Int] :: Ordering[Double] :: Ordering[String] :: HNil
val l3 = Ordering[Int] :: Ordering[Double] :: Ordering[Char] :: HNil
Y luego:
scala> foo(l1, l2)
scala> foo(l1, l3)
<console>:17: error: could not find implicit value for parameter ev: ...
Como se esperaba.Para 2.0 simplemente agregue un shapeless.ops.hlist._
importar y reemplazar MappedAux
con Mapped.Aux
y estás listo para partir.