如何从 Scala HList 中读取元素?
How to read an element from a Scala HList?
关于 HLists 的可读文档很少,我可以在 SO 上找到的答案来自外部 space 对于一个不起眼的 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??
有人可以解释一下我如何从那只恐龙中提取特定值吗?
只有一件事...如果它不是太重要,那么就坚持 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
我希望您的 row(0)
查找工作基于 HList API doc for 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
关于 HLists 的可读文档很少,我可以在 SO 上找到的答案来自外部 space 对于一个不起眼的 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??
有人可以解释一下我如何从那只恐龙中提取特定值吗?
只有一件事...如果它不是太重要,那么就坚持 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
我希望您的 row(0)
查找工作基于 HList API doc for 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