【问题标题】:Structural Programming in Scala with Shapeless: How to use the SYB implementation correctly?Scala 中的无形结构编程:如何正确使用 SYB 实现?
【发布时间】:2013-11-09 19:14:09
【问题描述】:

我想用Shapeless library中的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)

我认为,类型参数B 需要以某种方式进行约束,以使 Shapeless 库的隐式宏适用,但我不知道如何。

这样的遍历函数可以用Shapeless写吗?

【问题讨论】:

    标签: scala generic-programming shapeless


    【解决方案1】:

    您需要为方法主体中可用的无处不在的组合器创建一个隐式见证,

    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)
    

    【讨论】:

      猜你喜欢
      • 2019-06-20
      • 2015-10-29
      • 2019-03-01
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      相关资源
      最近更新 更多