7

shapeless を使用して、タイプセーフな方法でオブジェクトを簡単に蓄積しようとしています。

:::問題は、concat( ) twoを実行したい場合ですHList。私は初心者(少なくともそう思われる)の問題に遭遇しています。コンテキスト内のPrepend暗黙的なインスタンスがありません。

しかし、 を調べるhlist.scalaと、ジェネリックがオブジェクトとimplicit defで定義されていることがわかります。PrependPrependAux

手動で追加import Prependしてimport PrependAuxも何も変わりませんでした(明らかに...)。

したがって、ここでコードを最小限に抑えます。

enter code here

import shapeless._
import HList._
import Prepend._
import PrependAux._

object test {

  val a:HList = 1 :: 4 :: "A" :: HNil
  val b:HList = "R" :: false :: HNil

  val c:HList = a ::: b   // <<<<<<<<<<< NEEDS A Prepend in the context 

}

コンソールで次のようにします。

[error]     test.scala:10: could not find implicit value for parameter prepend: shapeless.Prepend[shapeless.HList,shapeless.HList]
[error]     val c:HList = a ::: b   // this needs an implicit Prepend in the current context

何が私の目を燃やすべきですか?

ありがとう

編集

下品化が以前は強すぎたため、実際の問題を少し再複雑化するための小さな更新。

これが私ができることのようなものです:

case class A[L<:HList](a:L) { 
  def doSmth[C <:HList](c:C) = a ::: c 
}

したがって、実際の型にアクセスすることはできません。それらがHListであることを知っているだけです。

4

1 に答える 1

11

へのアップキャストHListがここでの問題です。普通の古いものでできることはほとんどありませんHList(新しい要素を追加することを除けば)。

より有益な型注釈を提供できます。

val a: Int :: Int :: String :: HNil = 1 :: 4 :: "A" :: HNil
val b: String :: Boolean :: HNil = "R" :: false :: HNil
val c: Int :: Int :: String :: String :: Boolean :: HNil = a ::: b

または、型を推論させるだけで、通常ははるかに便利です。

val a = 1 :: 4 :: "A" :: HNil
val b = "R" :: false :: HNil
val c = a ::: b

あなたのコメントに応えて: 必要な証拠があることを確認すれば、やりたいことを実行できます (これa: Aは のタイプミスであり、これが機能するためにa: L必要であることに注意してください-Ydependent-method-types):

case class A[L <: HList](a: L) {
  def doSmth[C <: HList](c: C)(implicit p: Prepend[L, C]) = a ::: c
}

一般に、使用している操作に必要な暗黙を調べて、メソッドに含めることができます。

于 2012-06-14T17:00:08.847 に答える