Advertisement
Guest User

Untitled

a guest
Oct 13th, 2014
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 2.45 KB | None | 0 0
  1. import scala.collection.immutable
  2.  
  3. sealed trait SP[-A, +B] {
  4.   def run(input: Stream[A]): Stream[B] = this match {
  5.     case Put(value, sp) => value #:: sp.run(input)
  6.     case Get(builder)   => input match {
  7.       case x #:: xs => builder(x).run(xs)
  8.       case _        => Stream.empty
  9.     }
  10.   }
  11. }
  12.  
  13. case class Get[A, B](builder: A => SP[A, B]) extends SP[A, B]
  14. case class Put[A, B](value: B, sp: SP[A, B]) extends SP[A, B]
  15.  
  16. object SP {
  17.   trait Category extends scalaz.Category[SP] {
  18.     def id[A]: SP[A, A] = Get(x => Put(x, id))
  19.     def compose[A, B, C](f: SP[B, C], g: SP[A, B]): SP[A, C] = (g, f) match {
  20.       case (_,         Put(v, sp)) => Put(v, compose(sp, g))
  21.       case (Get(b),    _         ) => Get(x => compose(f, b(x)))
  22.       case (Put(v, sp), Get(b)   ) => compose(b(v), sp)
  23.     }
  24.   }
  25.  
  26.   trait Arrow extends scalaz.Arrow[SP] with Category {
  27.     def arr[A, B](f: (A) => B): SP[A, B] = Get(a => Put(f(a), arr(f)))
  28.     def first[A, B, C](f: SP[A, B]): SP[(A, C), (B, C)] = delay(f, immutable.Queue.empty)
  29.  
  30.     private def delay[A, B, C](sp: SP[A, B], q: immutable.Queue[C]): SP[(A, C), (B, C)] = sp match {
  31.       case Get(b)     => Get { case (a, c) => delay(b(a), q.enqueue(c)) }
  32.       case Put(v, sp) => if (q.isEmpty) Get { case (_, c) => Put((v, c), delay(sp, q)) }
  33.       else {
  34.         val (c, rest) = q.dequeue
  35.         Put((v, c), delay(sp, rest))
  36.       }
  37.     }
  38.   }
  39.  
  40.   implicit object arrow extends Arrow
  41. }
  42.  
  43. object StreamProcessors extends App {
  44.   import scalaz.std.function.function1Instance
  45.   import scalaz.syntax.arrow._
  46.   import SP.arrow._
  47.  
  48.   implicit def biUntupled[A,B,C](f: ((A, B)) => C): (A, B) => C = Function.untupled(f)
  49.  
  50.   def pairwise[A, B, C](f: (A, A) => (B, C)): SP[A, (B, C)] =
  51.     Get(x => Get(y => Put(f(x, y), pairwise(f))))
  52.  
  53.   def addMul(x: Int, y: Int) = (x + y, x * y)
  54.  
  55.   println(pairwise(addMul).run(Stream(1,2,3,4,5,6)).force)
  56.   //= Stream((3,2), (7,12), (11,30))
  57.  
  58.   def dup[X]: SP[X, X] = Get(x => Put(x, Put(x, dup)))
  59.  
  60.   def biwindow[A, B, C](f: (A, A) => (B, C)): SP[A, (B, C)] =
  61.     (Get(x => Put(x, dup)): SP[A, A]) >>> pairwise(f)
  62.  
  63.   println(biwindow(addMul).run(Stream(1,2,3,4,5,6)).force)
  64.   //= Stream((3,2), (5,6), (7,12), (9,20), (11,30))
  65.  
  66.   val add1 = (_ : Int) + 1
  67.   val mul2 = (_ : Int) * 2
  68.   val neg  = -(_: Int)
  69.  
  70.   val pipeline = biwindow(mul2 *** add1) >>> first(arr(neg))
  71.  
  72.   println(pipeline.run(Stream(1,2,3,4,5,6)).force)
  73.   //= Stream((-2,3), (-4,4), (-6,5), (-8,6), (-10,7))
  74. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement