2017-01-13 8 views
3

HListに関する読解可能なドキュメントはほとんどなく、私がSO上に見つけることができる答えは、宇宙から来て、謙虚なScala初心者のためです。Scala HListから要素を読み込む方法は?

Slickがデータベース行を表すためにいくつかを自動的に生成できるので、HListsが発生しました。彼らは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 

現在、これらの行の1つを与えられ、私は可能な場合は入力された、一つの要素を読み取るために必要があると思います。私はちょうどそれを行うことはできません。試しました

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?? 

誰かがその恐竜から特定の価値を引き出す方法を教えてください。

+0

......「恐竜」....あなたは 'HList'sのことがかなり恐ろしいですね。 –

+1

@SarveshKumarSinghあなたが知らない人の性格を反映した意見を出す必要はありません。あなたはそのコメントを削除することを提案できますか? – maasg

答えて

1

私はあなたの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 

これが機能しない場合は、表示されるエラーを共有できますか。

+0

この新しいインポートを試しましたが、 'row.head'の型が' Int'であっても 'row(0)'は 'Any'型です。 – JulienD

+0

ああ待って、IntellIJはエラー(「Anyは予想されるタイプIntに適合しません」)として下線を引いていますが、実際にコンパイルします。私はこれがいかに可能か理解していない。 – JulienD

+1

2つのこと: 'row(0)'の結果は最終的に 'Int'であるタイプエイリアスであり、IntelliJはそれによって混乱するかもしれません。また、IntelliJの混乱の原因となる可能性のあるマクロを見つけ出すのには、マクロがあります。私は知らない:-(また、実行時の値を使用している場合(valn = 0; row (行)のようなリテラルとは対照的に ''(n) ''と書かれています) '' Any''で終わるだろうと思っています –

0

ちょうど1つ...ちょうどとしてHListに固執することよりもそれほど重要でない場合...必要がない限りaliasMyRowにしないでください。

..だからあなたはこれについて

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 
+0

Sbtは "シンボル ':::'を解決できません。 2番目の解決策は、私が現時点で使用しているものです。要素12,14,15,17,26,27が必要だと想像してください...しかし、他に解決策がなければ、私はそれを保つでしょう。 – JulienD

+0

この ":::"はscaladocsにありますが、パターンマッチングでは機能しません。 '.tail.tail.tail ...'の代わりに '.drop'を使う方法があるはずですが、それを動作させることはできませんでした。しかし、お返事ありがとうございます。 – JulienD

関連する問題