Scala monad在未来携带HTTP url / params [T]

时间:2014-05-16 14:02:10

标签: scala monads json4s

我在scala中实现了以下monad,它使用用于请求的URL和params包装调度结果

import org.json4s._
import scala.concurrent.{ExecutionContext, Future}

case class Result[T](url:String,params:JValue,result:Future[T]) {
  self =>
  def flatMap[S](f: T => Result[S])(implicit executionContext:ExecutionContext):Result[S] = {
    val result_ = f andThen (_.result)
    Result(self.url,self.params,this.result flatMap result_)
  }

  def map[B](f: T => B)(implicit executionContext:ExecutionContext):Result[B] =
    Result(this.url,this.params,this.result map f )

}

我遇到的问题是flatmap的定义。要使flatmap更正,urlparams需要来自f,即f: T => Result[S]。在上面的示例中,虽然它编译得很好并且签名正是我所需要的,但self.urlself.params表示urlparams永远不会更新Result正在flatMap,换句话说,我不知道如何从{{1}的应用中获取urlparam个变量当f被调用时。

虽然flatMap需要T,但Request[S]url并不需要{}},那么scala的分离方式是什么?来自params的{​​{1}},因此我可以正确定义url,params

注意:monad背后的一般目的是这样我可以使用result调度结果(即flatMap),同时能够随身携带HTTP和{{1}用于请求,Future[T]更新urlparamsflatMaps(这是一个新请求),其中地图只修改url

编辑:以下是我目前如何使用monad

的示例
params

请注意,之前,这个理解仅适用于result,但是这样做会丢失使用的URL /参数

1 个答案:

答案 0 :(得分:1)

flatMap的规范定义将类似于:

def flatMap(f: A => M[B]): M[B]

本质上是确定性的。在您的情况下,您试图在一个行动中强加确定性的构成,其中所需的值以非确定性的方式给出。因此,你的麻烦。

如果您想以确定的方式回归,那么您必须使用Await

def flatMap[B](f: A => Result[B]): Result[B] = Await result (result map f)

首先完全违背了使用Future的目的。表征对象的更好方法是从内部删除Future并将其与外部包围:

case class Result(url: String, params: JValue, result: T){
  def map[R](f: T => R) = copy(result = f(result))
  def flatMap[R](f: T => Result[R]) = f(result)
}

因此,Future只会通过应用程序异步地评估函数(String, JValue) => Result[T]进入场景。