我正在尝试实现一个使用可遍历对象操作的函数。
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])
}
}
答案 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]
同步M
和Traversable
中的类型漏洞。因此无论在M
中放置什么类型,它都将放在Traversable