我已经在 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
正确,url
andparams
需要来自f
,即f: T => Result[S]
。在上面的示例中,虽然它编译得很好并且签名正是我所需要的,但self.url
andself.params
意味着url
and永远不会被正在编辑params
的 that 更新,换句话说,我不知道如何获取and变量从何时被调用的应用程序。Result
flatMap
url
param
f
flatMap
尽管T
是必需的,但andRequest[S]
却不是必需的,那么从 the中分离出来的 scala 方法是什么,以便我可以正确定义?url
params
url,params
result
flatMap
注意: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/参数