Advertisement
Guest User

Untitled

a guest
Apr 14th, 2014
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 3.20 KB | None | 0 0
  1. package com.rr.sinks
  2. package util
  3.  
  4. import language._
  5.  
  6. import scala.concurrent.duration.Duration
  7.  
  8. import scalaz._
  9. import scalaz.effect._
  10. import scalaz.syntax.monad._
  11.  
  12. // note that F[A] === F[TimeoutT[Identity, A]]
  13. final class TimeoutT[F[_], A] private[util] (private[util] val fa: F[A], private[util] val delay: Duration, private[util] val transform: A => TimeoutT[F, A]) {
  14.   private[this] val init = System.currentTimeMillis
  15.  
  16.   def run(implicit FL: LiftIO[F], F: Monad[F]): F[A] = {
  17.     val back = if (delay.isFinite) {
  18.       val check = FL.liftIO(IO { System.currentTimeMillis < init + delay.toMillis })
  19.      
  20.       check flatMap { flag =>
  21.         if (flag)
  22.           fa
  23.         else
  24.           fa flatMap { transform(_).run }
  25.       }
  26.     } else {
  27.       fa
  28.     }
  29.    
  30.     back
  31.   }
  32.  
  33.   def flatMap[B](f: A => TimeoutT[F, B])(implicit FL: LiftIO[F], F: Monad[F]): TimeoutT[F, B] = {
  34.     val fa = run flatMap { fa =>
  35.       f(fa).run
  36.     }
  37.    
  38.     TimeoutT(fa)
  39.   }
  40.  
  41.   def map[B](f: A => B)(implicit FL: LiftIO[F], F: Monad[F]): TimeoutT[F, B] = TimeoutT(run map f)
  42. }
  43.  
  44. object TimeoutT extends TimeoutTInstances {
  45.   def apply[F[_], A](fa: F[A]): TimeoutT[F, A] =
  46.     new TimeoutT(fa, Duration.Inf, { _: A => sys.error("assertion error") })        // definitional failure if we hit this case
  47.  
  48.   def setTimeout[F[_], A](a: F[A], delay: Duration)(transform: A => TimeoutT[F, A]): TimeoutT[F, A] =
  49.     new TimeoutT(a, delay, transform)
  50. }
  51.  
  52. sealed abstract class TimeoutTInstances1 {
  53.   implicit def timeoutTFunctor[F[_], A](implicit FL0: LiftIO[F], F0: Monad[F]): Functor[({ type λ[α] = TimeoutT[F, α] })#λ] = new TimeoutTFunctor[F] {
  54.     def FL = FL0
  55.     def F = F0
  56.   }
  57. }
  58.  
  59. sealed abstract class TimeoutTInstances0 extends TimeoutTInstances1 {
  60.   implicit def timeoutTMonad[F[_], A](implicit FL0: LiftIO[F], F0: Monad[F]): Monad[({ type λ[α] = TimeoutT[F, α] })#λ] = new TimeoutTMonad[F] {
  61.     def FL = FL0
  62.     def F = F0
  63.   }
  64. }
  65.  
  66. sealed abstract class TimeoutTInstances extends TimeoutTInstances0 {
  67.   implicit val timeoutTMonadTrans: Hoist[TimeoutT] = new TimeoutTHoist {}
  68. }
  69.  
  70. private trait TimeoutTFunctor[F[_]] extends Functor[({ type λ[α] = TimeoutT[F, α] })#λ] {
  71.   implicit def FL: LiftIO[F]
  72.   implicit def F: Monad[F]
  73.  
  74.   override def map[A, B](fa: TimeoutT[F, A])(f: A => B): TimeoutT[F, B] = fa map f
  75. }
  76.  
  77. private trait TimeoutTMonad[F[_]] extends Monad[({ type λ[α] = TimeoutT[F, α] })#λ] {
  78.   implicit def FL: LiftIO[F]
  79.   implicit def F: Monad[F]
  80.  
  81.   def point[A](a: => A): TimeoutT[F, A] = TimeoutT(F point a)
  82.  
  83.   def bind[A, B](fa: TimeoutT[F, A])(f: A => TimeoutT[F, B]): TimeoutT[F, B] = fa flatMap f
  84. }
  85.  
  86. private trait TimeoutTHoist extends Hoist[TimeoutT] {
  87.   // monad constraint is actually unnecessary here except to preserve signature
  88.   def liftM[G[_]: Monad, A](a: G[A]): TimeoutT[G, A] = TimeoutT(a)
  89.  
  90.   def hoist[M[_]: Monad, N[_]](f: M ~> N) = new (({ type λ[α] = TimeoutT[M, α] })#λ ~> ({ type λ[α] = TimeoutT[N, α] })#λ) {
  91.     def apply[A](fa: TimeoutT[M, A]): TimeoutT[N, A] = {
  92.       new TimeoutT(f(fa.fa), fa.delay, fa.transform andThen apply)
  93.     }
  94.   }
  95.  
  96.   def apply[G[_]: Monad]: Monad[({ type λ[α] = TimeoutT[G, α] })#λ] = ???
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement