我已经在 scala 中实现了以下 monad,它使用用于请求的 URL 和参数包装了调度结果
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正确,urlandparams需要来自f,即f: T => Result[S]。在上面的示例中,虽然它编译得很好并且签名正是我所需要的,但self.urlandself.params意味着urland永远不会被正在编辑params的 that 更新,换句话说,我不知道如何获取and变量从何时被调用的应用程序。ResultflatMapurlparamfflatMap
尽管T是必需的,但andRequest[S]却不是必需的,那么从 the中分离出来的 scala 方法是什么,以便我可以正确定义?urlparamsurl,paramsresultflatMap
注意:monad 背后的一般目的是让我可以处理HTTP调度的结果(即Future[T]),同时能够携带url和params用于请求,flatMaps更新url,params和result(它是一个新请求),其中映射只是修改result
编辑:这是我当前如何使用 monad 的示例
val restResponse = for {
token <- Authenticate.Helpers.mainLogin // Type Result[String]
userSessionToken <- Authenticate.Helpers.loginToken("someUser","somePassword",token) // Type Result[String]
someOtherCommand <- DataService.getInitialData(token,userSessionToken) map
(_ \ "someData" \ "someMoreData" \\ "evenMoreData" match {
case JString(s) => s
case JArray(items) =>
items.collectFirst { case JString(s) =>s}.head
}) // Type Result[String], the map is working over the `JValue` inside Future[JValue] that is held within the Request[JValue]
someData <- DataService.getData(token,userSessionToken) // Type Result[JValue]
} yield itemSummaries
println(restResponse.url) // should print the url of someData, but is instead printing the url of token. restResponse.result is the correct value however
请注意,在此之前,这只是为了理解Future[T],但是这样做我丢失了使用的 URL/参数