Как читать элемент из Scala HList?

Существует очень мало читаемой документации о HLists, и ответы, которые я могу найти на SO, приходят из космоса для скромного новичка в Scala.

Я столкнулся с HLists, потому что Slick может автоматически генерировать некоторые для представления строк базы данных. Они есть slick.collection.heterogeneous.HList (не бесформенный). Пример:

type MyRow = HCons[Int,HCons[String,HCons[Option[String],HCons[Int,HCons[String,HCons[Int,HCons[Int,HCons[Option[Int],HCons[Option[Float],HCons[Option[Float],HCons[Option[String],HCons[Option[String],HCons[Boolean,HCons[Option[String],HCons[Option[String],HCons[Option[String],HCons[Option[String],HCons[Option[String],HCons[Option[Int],HCons[Option[Float],HCons[Option[Float],HCons[Option[Float],HCons[Option[String],HCons[Option[String],HNil]]]]]]]]]]]]]]]]]]]]]]]]
def MyRow(a, b, c, ...): MyRow = a :: b :: c :: ... :: HNil

Теперь, учитывая одну из этих строк, мне нужно прочитать один элемент, напечатанный, если это возможно. Я просто не могу этого сделать. Я старался

row(4)  // error
row._4  // error
row.toList  // elements are inferred as Any
row match { case a :: b :: c :: x :: rest => x }  // "Pattern type is incompatible. Expected MyRow."
row match { case MyRow(_,_,_,_,_,x,...) => x }  // is not a case class like other rows
row match { HCons[Int,HCons[String,HCons[Option[String],HCons[Int,HCons[String, x]]]]] => x.head }  // error
row.tail.tail.tail.tail.head  // well, is that really the way??

Может кто-нибудь объяснить, как я могу извлечь определенную ценность из этого динозавра?

2 ответа

Решение

Я бы ожидал твоего row(0) поиск для работы на основе документа HList API дляapply, Вот пример, который я пробовал с Slick 3.1.1:

scala> import slick.collection.heterogeneous._
import slick.collection.heterogeneous._

scala> import slick.collection.heterogeneous.syntax._
import slick.collection.heterogeneous.syntax._

scala> type MyRow = Int :: String :: HNil
defined type alias MyRow

scala> val row: MyRow = 1 :: "a" :: HNil
row: MyRow = 1 :: a :: HNil

scala> row(0) + 99
res1: Int = 100

scala> val a: String = row(1)
a: String = a

Если это не работает, не могли бы вы поделиться ошибкой, которую вы видите.

Только одно... если это не слишком важно, чем просто придерживаться HList как type, Не делайте alias это к MyRow если не нужно.

Итак.. у вас было

val row = a :: b :: c :: ... :: HNil

Как насчет этого?

val yourX = row match { case a :: b :: c :: x ::: rest => x }

заметить, что ::: вместо :: в конце.

Или... как насчет этого,

val yourX = row.tail.tail.tail.head

// this may change a little if you had,
def MyRow(a, b, c, ...): MyRow = a :: b :: c :: ... :: HNil

val row = MyRow(a, b, c, ...)

val yourX = row.asInstanceOf[HList].tail.tail.tail.head
Другие вопросы по тегам