1

次のようなことをしたいと思います。

val foo = List[B <% JValue] = 42 :: "hello" : Nil

JValueリストのメンバーをsに変換できることをコンパイラが認識できるようにします。

ただし、これはコンパイルされません。List[Any]JValues に変換できる値が期待される場所でそのメンバーを使用する必要があるため、次のように満足することはできません。

def fun[A <% JValue](x: List[A]) = ...

これを解決する方法はありますか?

4

3 に答える 3

2

Luigi Plinge答え|:からの方法の少しの改善:

あなたは書くことができます

val foo: List[JValue] = 42 :: "hello" :: HNil

適切な暗黙の変換 ( shapelessを使用):

import shapeless._

trait HListTConv[H <: HList, T] {
  def apply(l: List[T], hl: H): List[T]
}

object HListTConv {
  implicit def apply0[T] = new HListTConv[HNil, T] {
    def apply(l: List[T], hl: HNil): List[T] = l
  }

  implicit def applyN[Head, Tail <: HList, T](implicit c: HListTConv[Tail, T], conv: Head => T) =
    new HListTConv[Head :: Tail, T] {
      def apply(l: List[T], hl: Head :: Tail): List[T] = (hl.head: T) :: c(l, hl.tail)
    }
}

implicit def hListToJValueList[H <: HList](hl: H)(implicit c: HListTConv[H, JValue]): List[JValue] = c(Nil, hl)

テスト:

case class Test(s: String)
implicit def intToTest(i: Int): Test = Test(i.toString)
implicit def strToTest(s: String): Test = Test(s)

implicit def hListToListTest[H <: HList](hl: H)(implicit c: HListTConv[H, Test]): List[Test] = c(Nil, hl)

scala> val foo: List[Test] = 42 :: "hello" :: HNil
foo: List[Test] = List(Test(42), Test(hello))
于 2013-07-08T05:00:08.020 に答える
0

暗黙の単純なセットを使用して変換を有効にすることができます。

class JValue
implicit intToJValue(x: Int) = new JValue
implicit stringToJValue(x: String) = new JValue

val xs: List[JValue] = List(1, "hello")

2 番目の質問では、次の方法で卸売リストの変換を有効にできます。

implicit def listToJList[A <% JValue](xs: List[A]): List[JValue] = xs
def foo[A <% JValue](x: List[A]): List[JValue] = x

上記の例は、uniform 型を使用している場合にのみ機能します。それ以外の場合は、より洗練された手段を採用する必要があります。ほとんどの場合、異種の型のリストは List[Any] に統合されます。

形状のない、最も採用されている shapless.Poly と HList を使用して、よりエレガントで複雑なソリューションを考え出すことができます。

于 2013-07-08T02:20:51.677 に答える