2017-06-12 86 views
1

我试图实现一个使用可遍历对象的函数。Traversable foldLeft的函数参数导致类型不匹配

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

看起来像在类型界限_问题,以字母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]并有一些类型的空洞。换句话说,它用Any填充Traversable中的类型孔,然后在M(不需要)中创建一个新的类型孔。

M[X] <: Traversable[X]同步MTraversable中的类型孔。所以,无论类型放在M它将被放置在Traversable

+0

谢谢!我错过了类型变量绑定。 – Zernike

相关问题