用于Apache Spark RDD的Scalaz类型类

mar*_*ios 6 functional-programming scala scalaz apache-spark rdd

目标是实现Scalaz为Spark的RDD(分布式集合)提供的不同类型类(如Semigroup,Monad,Functor等).不幸的是,我不能使任何采用更高级别类型(如Monad,Functor等)的类型类与RDD一起使用.

RDD被定义(简化)为:

abstract class RDD[T: ClassTag](){
   def map[U: ClassTag](f: T => U): RDD[U] = {...}
}
Run Code Online (Sandbox Code Playgroud)

可以在此处找到完整的RDD代码.

这是一个很好的例子:

import scalaz._, Scalaz._
import org.apache.spark.rdd.RDD

implicit def semigroupRDD[A] = new Semigroup[RDD[A]] {
   def append(x:RDD[A], y: => RDD[A]) = x.union(y)
}
Run Code Online (Sandbox Code Playgroud)

这是一个不起作用的例子:

implicit def functorRDD =  new Functor[RDD] {
   override def map[A, B](fa: RDD[A])(f: A => B): RDD[B] = {
      fa.map(f)
   }
}
Run Code Online (Sandbox Code Playgroud)

这失败了:

错误:没有ClassTag可用于B fa.map(f)

错误很清楚.在RDD中实现的地图需要ClassTag(见上文).ScalaZ仿函数/ monad等没有ClassTag.甚至可以在不修改Scalaz和/或Spark的情况下完成这项工作吗?

ade*_*rtc 10

简答:不

对于类型类Functor,限制是对任何 AB不受约束的限制,因为A => B你有一个函数被解除RDD[A] => RDD[B].在星火你不能挑任意AB,因为你需要ClassTagB,正如你所看到的.

对于其他类型的类,例如Semigroup在操作期间类型没有改变,因此不需要a ClassTag,它可以工作.