2016-04-17 38 views
6

Celem jest zaimplementowanie różnych klas typów (takich jak półgrupa, monada, funktor itp.) Dostarczonych przez Scalaz dla RDD Sparka (kolekcja rozproszona). Niestety, nie mogę wykonać żadnej z klas, które przyjmują typy o wyższych typach (takie jak Monad, Functor itp.), Aby dobrze współpracować z RDD.Klasy typu Scalaz dla Apache Spark RDD

ZOPS są zdefiniowane (uproszczonych) jako:

abstract class RDD[T: ClassTag](){ 
    def map[U: ClassTag](f: T => U): RDD[U] = {...} 
} 

pełna kod ZOPS można znaleźć here.

Oto jeden przykład, który działa dobrze:

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) 
} 

Oto jeden przykład, który nie działa:

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

ten nie powiedzie się z:

error: No ClassTag available for B fa.map(f)

błędu jest całkiem jasne. Mapa zaimplementowana w RDD oczekuje klasy ClassTag (patrz wyżej). ScalaZ funktor/monady itp., Nie mają ClassTag. Czy możliwe jest wykonanie tej pracy bez modyfikowania Scalaz i/lub Spark?

Odpowiedz

10

Krótka odpowiedź: nie

Dla klas typu jak Functor, ograniczenie jest, że dla dowolnyA i B, swobodnej, zważywszy A => B masz funkcją podniósł RDD[A] => RDD[B]. W Sparku nie można wybrać dowolnych A i B, ponieważ potrzebujesz ClassTag dla B, jak widziałem.

Dla innych klas, takich jak Semigroup, gdzie typ nie zmienia się podczas operacji i dlatego nie potrzebuje ClassTag, działa.

+1

To był także mój wniosek. – marios