1

HList と派生 HList を返す方法を知っている型クラスを作成したいと思います。理想的には、次のような構造になります。

trait Axis[A, L1 <: HList] {
  type L2 <: Mapped[L1,Ordering]#Out
  def vectorize(a:A): L1
  def orderings: L2
}

そして次のように実装されます

implicit object Tup2DI extends Axis[(Double, Int), Double :: Int :: HNil] {
  val m = implicitly[Mapped[Double :: Int :: HNil, Ordering]]
  type L2 = m.Out
  def vectorize(a: (Doubble, Int)) = a._1 :: a._2 :: HNil
  def orderings = implicitly[Ordering[Double]] :: implicitly[Ordering[Int]] :: HNil
}

問題は、型を特定するのに十分な情報があるにもかかわらず、scala が型を具体化していないため、コンパイル中に、次のエラーが発生することです。

 found   : shapeless.::[Ordering[Double],shapeless.::[Ordering[Int],shapeless.HNil]]
 required: Tup2DI.L2
    (which expands to)  Tup2DI.m.Out
             def orderings:L2 = implicitly[Ordering[Double]] :: implicitly[Ordering[Int]] :: HNil

関心のある情報を正しくコンパイルする方法で表現するにはどうすればよいですか?

4

1 に答える 1

0

よし、#scala に精通した人々と話し合った後、次の回避策が指摘されました。

trait Axis[A, L1 <: HList] {
  val L2: Mapped[L1,Ordering]
  def vectorize(a:A): L1
  def orderings: L2.Out
}
object Axis {
  def reifiedT[L1 <: HList](implicit M: Mapped[L1,Ordering]): Mapped[L1,Ordering] {
    type Out = M.Out
  } = M
}

implicit object Tup2DI extends Axis[(Double, Int), Double :: Int :: HNil] {
  val L2 = Axis.reifiedT[L]
  def vectorize(a: (Double, Int)) = a._1 :: a._2 :: HNil
  def orderings:L2.Out = implicitly[Ordering[Double]] :: implicitly[Ordering[Int]] :: HNil
}

どうやら、具体化された Out 型を明示的に設定するように scala に指示する必要があるようです。これは、Scalaz ライブラリで使用されている手法です。

于 2014-01-08T23:41:12.520 に答える