Last active
March 26, 2018 16:48
-
-
Save erikerlandson/a784411bc2bce5a8fbafddc3cc3e0b3c to your computer and use it in GitHub Desktop.
sifting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
scala> :load /home/eje/sift.scala | |
Loading /home/eje/sift.scala... | |
defined module sift | |
defined module demo | |
scala> import sift._ | |
import sift._ | |
scala> val r = Sifted.seq(demo.dirty).map(_.map(_.toDouble)).filter(_(0) > 1).map(_(1)) | |
r: sift.SiftedSeq[Double,scala.collection.immutable.Vector,(scala.collection.immutable.Vector[scala.collection.immutable.Vector[Double]], (scala.collection.immutable.Vector[scala.collection.immutable.Vector[Double]], (scala.collection.immutable.Vector[scala.collection.immutable.Vector[String]], List[Nothing])))] = SiftedSeq(Vector(5.0),(Vector(Vector(3.0)),(Vector(Vector()),(Vector(Vector(2, 3, z)),List())))) | |
scala> r.passed | |
res0: scala.collection.immutable.Vector[Double] = Vector(5.0) | |
scala> r.retained | |
res1: (scala.collection.immutable.Vector[scala.collection.immutable.Vector[Double]], (scala.collection.immutable.Vector[scala.collection.immutable.Vector[Double]], (scala.collection.immutable.Vector[scala.collection.immutable.Vector[String]], List[Nothing]))) = (Vector(Vector(3.0)),(Vector(Vector()),(Vector(Vector(2, 3, z)),List()))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object sift { | |
import scala.language.reflectiveCalls | |
import scala.language.higherKinds | |
import scala.language.implicitConversions | |
import scala.collection.SeqLike | |
import scala.collection.generic.CanBuildFrom | |
import scala.util.Either | |
type Seive[T, U] = T => Either[T, U] | |
def liftToSeive[T, U](f: T => U): Seive[T, U] = { | |
(t: T) => try { | |
Right(f(t)) | |
} catch { | |
case _: Throwable => Left(t) | |
} | |
} | |
case class SiftedSeq[T, S[E] <: SeqLike[E, S[E]], R](passed: S[T], retained: R) { | |
def map[U](f: T => U)(implicit cbf1: CanBuildFrom[S[T], Either[T,U], S[Either[T,U]]], cbf2: CanBuildFrom[S[Either[T,U]], Either[T,U], S[Either[T,U]]], cbf3: CanBuildFrom[S[Either[T,U]], U, S[U]], cbf4: CanBuildFrom[S[Either[T,U]], T, S[T]]): SiftedSeq[U, S, (S[T], R)] = { | |
val s = passed.map(liftToSeive(f)) | |
val p = s.filter(_.isRight).map(_.right.get) | |
val r = s.filter(_.isLeft).map(_.left.get) | |
SiftedSeq[U, S, (S[T], R)](p, (r, retained)) | |
} | |
def filter(f: T => Boolean)(implicit cbf1: CanBuildFrom[S[T], T, S[T]]): SiftedSeq[T, S, (S[T], R)] = { | |
val fs = liftToSeive(f) | |
val p = passed.filter { e => | |
val t = fs(e) | |
t.isRight && t.right.get | |
} | |
val r = passed.filter { e => fs(e).isLeft } | |
SiftedSeq[T, S, (S[T], R)](p, (r, retained)) | |
} | |
} | |
object Sifted { | |
def seq[T, S[E] <: SeqLike[E, S[E]]](data: S[T]) = SiftedSeq[T, S, List[Nothing]](data, Nil) | |
} | |
} | |
object demo { | |
val dirty = Vector( | |
Vector("1", "2", "3"), | |
Vector("2", "3", "z"), | |
Vector(), | |
Vector("3"), | |
Vector("4", "5") | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment