Как читать элемент из 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