Как заархивировать HList с простой коллекцией Scala? - PullRequest
0 голосов
/ 06 декабря 2018

Как заархивировать HList, скажем, с помощью Scala Stream, чтобы создать HList пар?В частности:

import shapeless._

val a = 1.3 :: true :: "z" :: HNil
val b = Stream.from(1)

val ab: (Double, Int) :: (Boolean, Int) :: (String, Int) :: HNil = ???

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Возможно, но есть ограничения.В основном вы должны указать желаемую длину коллекции Scala для архивирования.Результатом, конечно, будет длина более короткого из двух списков HL.

import shapeless._
import syntax.std.traversable._  // toHList

val a = 1.3 :: true :: "z" :: HNil  // 3 elements

val short_b = Stream.from(1).take(2).toHList[Int::Int::HNil]
val long_b  = Stream.from(7).take(5).toHList[Int::Int::Int::Int::Int::HNil]

toHList возвращает Option[HList], поэтому мы будем map по результатам, чтобы извлечь HList быть застегнутым.

short_b.map(a zip _)  // 2 element result
//res0: Option[(Double, Int) :: (Boolean, Int) :: HNil] =
// Some((1.3,1) :: (true,2) :: HNil)

long_b.map(a zip _)  // 3 element result
//res1: Option[(Double, Int) :: (Boolean, Int) :: (String, Int) :: HNil] =
// Some((1.3,7) :: (true,8) :: (z,9) :: HNil)
0 голосов
/ 06 декабря 2018
trait Zipper[A <: HList, B] {
  type Out <: HList
  def zip(a: A, bs: Stream[B]): Out
}

implicit def hnilZipper[B] = new Zipper[HNil, B] {
  type Out = HNil
  def zip(a: HNil, bs: Stream[B]): HNil = HNil
}

implicit def consZipper[Head, Tail <: HList, B](implicit z: Zipper[Tail, B]) = new Zipper[Head :: Tail, B] {
  type Out = (Head, B) :: z.Out
  def zip(a: Head :: Tail, bs: Stream[B]): Out = {
    (a.head, bs.head) :: z.zip(a.tail, bs.tail)
  }
}

def zip[A <: HList, B](a: A, b: Stream[B])(implicit z: Zipper[A, B]): z.Out = z.zip(a, b)

Как отмечает Март, существуют проблемы с безопасностью, и это не удастся, если поток будет короче HList.Но вы можете довольно легко изменить это, чтобы вернуть Option[(A1, B) :: (A2, B) :: ...] или (A1, Option[B]) :: (A2, Option[B]) :: ..., если это проблема.

...