/ / In forma informe, avere due liste come quella che contiene i typeclass dell'altro - scala, shapeless

In forma informe, hai due liste come quella che contiene i typeclass dell'altro: scala, senza forma

In forma informe sto cercando di scrivere una funzione tale da richiedere due HLists l1 e l2 di lunghezza arbitraria che presentano le seguenti proprietà:

  1. Lunghezza di l1 e l2 sono uguali
  2. l2 contiene i tipi esatti di l1, avvolto in un costruttore di tipo esterno costante.

Quindi se l1 era

1 :: 1.2 :: "hello" :: HNil`

l2 potrebbe essere

Ordering[Int] :: Ordering[Double] :: Ordering[String] :: HNil

utilizzando UnaryTCConstraint e LengthAux mi consente di limitare le lunghezze e richiede un costruttore esterno statico per l2, tuttavia averli conformi è diventato un problema.

Qualche idea su come potrei farlo?

risposte:

9 per risposta № 1

Mapped fornisce precisamente questo vincolo senza l'ulteriore necessità di Length. A partire dal la documentazione:

Tipo classe testimone che il risultato di avvolgere ogni elemento di HList L nel tipo di costruttore F è Out.

Ecco come appare in 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

E poi:

scala> foo(l1, l2)

scala> foo(l1, l3)
<console>:17: error: could not find implicit value for parameter ev: ...

Come previsto. Per 2.0 basta aggiungere un shapeless.ops.hlist._ importa e sostituisci MappedAux con Mapped.Aux e sei pronto ad andare.