我提出的另一個解決方案
def iterate[F[_],A](init: A)(f: A => F[A]): Process[F, A] = {
Process.emit(init) ++ Process.await(f(init)) { next => iterate(next)(f)}
}
這已經是scalaz流0.6的特徵,請參閱本pr詳細
中序使用scala.concurrent.Future
作爲上下文類型F
我們需要import scalaz.std.scalaFuture._
和Catchable
例如
implicit def futureCatchable(implicit ctx: ExecCtx): Catchable[Future] = {
new Catchable[Future] {
def attempt[A](f: Future[A]) = f.map(\/-(_)).recover { case e => -\/(e)}
def fail[A](err: Throwable) = Future.failed(err)
}
}
最後我得到這個:
package stream
import scala.concurrent._
import scalaz._
import scalaz.stream._
package object future {
type ExecCtx = ExecutionContext
def iterate[F[_],A](init: A)(f: A => F[A]): Process[F, A] = {
Process.emit(init) ++ Process.await(f(init)) { next => iterate(next)(f)}
}
implicit def futureCatchable(implicit ctx: ExecCtx): Catchable[Future] = {
new Catchable[Future] {
def attempt[A](f: Future[A]) = f.map(\/-(_)).recover { case e => -\/(e)}
def fail[A](err: Throwable) = Future.failed(err)
}
}
}
object futureApp extends App {
import scalaz.Scalaz._
import future._
import scala.concurrent.ExecutionContext.Implicits.global
def get(i: Int) = Future {
println(i + 1)
i + 1
}
iterate(0)(get).takeWhile(_ < 100000).run
}
這是一個有點不清楚(至少對我來說)你問。 'Process.eval'可以讓你將'Future [A]'變成'Process [Future,A]' - 這可能是你想要開始的地方。你需要'Future'的'Catchable'實例來運行它,但是這不應該太難寫。 – 2014-09-11 14:37:55
@TravisBrown我已經讓我的問題更加詳細,可以看看它。 – jilen 2014-09-12 00:11:33