Traversable foldLeft的函数参数导致类型不匹配

时间:2017-06-12 12:14:08

标签: scala

我正在尝试实现一个使用可遍历对象操作的函数。

def f[V, M[_] <: Traversable[_]](ei: M[V])(builder: GenericCompanion[M]): M[V] =
  ei.foldLeft(builder.empty[V])((accum: M[V], el: V) => builder(el))

由于

,此代码无法编译
Error:(22, 57) type mismatch;
 found   : el.type (with underlying type Any)
 required: V
  ei.foldLeft(builder.empty[V])((accum, el) => builder(el))
                                                       ^

使用scala 2.11.8和2.12.1重现。这很奇怪。为什么el被假定为Any

我可以用猫库解决它。所以问题不是'怎么做?'但'为什么纯scala代码错了?'。

def f[V, M[_] : Foldable : Alternative](ei: M[V]): M[V] = {
  val monoidK = implicitly[MonoidK[M]]

  ei.foldLeft(monoidK.empty[V]) {
    (accum, el) => monoidK.algebra[V].combine(accum, el.pure[M])
  }
}

1 个答案:

答案 0 :(得分:1)

类似于_的类型边界中的问题,在用它编译的字母X替换之后。

def f[V, M[X] <: Traversable[X]](ei: M[V])(builder: GenericCompanion[M]): M[V] =
  ei.foldLeft(builder.empty[V])((accum: M[V], el: V) => builder(el))

看看this answer的某些直觉。据我了解

M[_] <: Traversable[_] M延伸Traversable[Any]并且有一些类型漏洞。换句话说,它会在Traversable中使用Any填充类型的洞,然后在M中创建一个新类型的洞(您不需要)。

M[X] <: Traversable[X]同步MTraversable中的类型漏洞。因此无论在M中放置什么类型,它都将放在Traversable