2

ShapelessライブラリのSYB実装を使用して、次の汎用トラバーサル関数を記述したいと考えています。

class Data

// Perform the desired manipulation on the given data 
object manipulate extends ->((data: Data) => data)

def traverseAndManipulate[B](expr: B): B = {
  everywhere(manipulate)(expr)
}

残念ながら、このコードは次の型エラーを生成します (Shapeless 2.0.0-M1 および Scala 2.10.2 を使用):

type mismatch;
[error]  found   : shapeless.EverywhereAux[SYB.manipulate.type]
[error]  required: ?{def apply(x$1: ? >: B): ?}
[error] Note that implicit conversions are not applicable because they are ambiguous:
[error]  both method inst1 in trait PolyInst of type [A](fn: shapeless.Poly)(implicit cse: fn.ProductCase[shapeless.::[A,shapeless.HNil]])A => cse.Result
[error]  and macro method apply in object Poly of type (f: Any)shapeless.Poly
[error]  are possible conversion functions from shapeless.EverywhereAux[SYB.manipulate.type] to ?{def apply(x$1: ? >: B): ?}
[error]     everywhere(manipulate)(expr)

BShapeless ライブラリの暗黙的なマクロを適用できるようにするには、型パラメーターを何らかの方法で制約する必要があると思いますが、その方法がわかりません。

このようなトラバーサル関数は、Shapeless を使用して記述できますか?

4

1 に答える 1

3

メソッドの本体で利用可能などこでもコンビネータの暗黙の証人を作成する必要があります。

def traverseAndManipulate[B](expr: B)
  (implicit e: Everywhere[manipulate.type, B]) = everywhere(manipulate)(expr)

現時点では推測できない理由によりtraverseAndManipulate、明示的な結果の型を指定するBと、コンパイラは同様のあいまいさを報告することに注意してください。ただし、結果の型は として正しく推論されBます。明示的な結果の型が必要な場合は、以下が同等である必要があります。

def traverseAndManipulate[B](expr: B)
  (implicit e: Everywhere[manipulate.type, B] { type Result = B }): B = e(expr)
于 2013-11-03T13:05:57.063 に答える