现代化的Java(三十五)——Future Monad
2009 年 4 月 2 日
今天在 Jaskell Dotty 里,增加了一个 monad instance:
given futureMonad (using ec:ExecutionContext): Monad[Future] with { def pure[A](x: A): Future[A] = Future.successful(x) extension[A, B] (x: Future[A]) { override def map(f: A => B): Future[B] = x.map(f) def flatMap(f: A => Future[B]): Future[B] = x.flatMap(f) } }
这个 instance 使得 scala.concurrent.Future 也可以遵循我们在 jaskell 中定义的 monad 行为,包括 applicative 。例如下面这个测试代码:
class FutureSpec extends AsyncFlatSpec with Matchers { import jaskell.futureMonad val future = Future("success") *> Future(3.14) {value => value * 2*2} value should be (3.14 * 2 * 2)) } }
因为这段代码旨在测试 monad 功能,所以没有做很复杂的异步逻辑测试。future 对象在前后三个任务都成功的前提下,返回中间 Future(3.14) >> {value => value 2 * 2} 的求值结果。
当然,实际上 scala 本身就支持类似 haskell do 的 for yield,future 的定义完全可以写成:
for { _ <- Future("success") result > {value => value * 2*2} _ <- Future("Right") } yield result