patternMinor
Too many nested Types?
Viewed 0 times
typesnestedtoomany
Problem
I have the following Scala code:
and I have a third function like this:
Which is supposed to concatenate the two Seq collections of Group objects together and return them as per the type signature. I'm really struggling to figure out how to do this though, as the types are so deeply nested.
Have I written my code badly or is there another way to do this?
def getLists(token: String, username: String):Future[Try[Seq[Group]]] = {
val result:Future[Try[JsValue]] = getAPIResult(token, "https://myapi.com/screen_name=" + username)
result.map( x => convertFromJsValueToObject(x))
}
def getSubscriptions(token: String, username: String):Future[Try[Seq[Group]]] = {...} //same as above
private def getAPIResult(token: String, apiCall: String):Future[Try[JsValue]] = {
WS.url(apiCall)
.withHeaders("Authorization" -> ("Bearer " + token))
.get().map(response =>
response.status match {
case 200 => Success(Json.parse(response.body))
case _ => Failure(new RuntimeException("Web service call failed: " + response.body))
})
}
private def convertFromJsValueToObject(json: Try[JsValue]): Try[Seq[Group]] = {
json match {
case Success(v) => {
Success(v.as[Seq[Group]])
}
case Failure(t) => Failure(t)
}
}and I have a third function like this:
def getAllListsAndSubscriptions(token: String, username: String):Future[Try[Seq[Group]]] = {...}Which is supposed to concatenate the two Seq collections of Group objects together and return them as per the type signature. I'm really struggling to figure out how to do this though, as the types are so deeply nested.
Have I written my code badly or is there another way to do this?
Solution
You should "lift" your functions instead.
For example, instead of defining:
use
directly in your code.
You can think of
If you have a
which lifts the same function
For example, instead of defining:
def getSomething(input: V): Future[FinalType] = {
val intermediate: IntermediaryType = complicatedFunctionReturningFuture(input)
mappingFunction(intermediate)
}use
complicatedFunctionReturningFuture(input).map(mappingFunction)directly in your code.
You can think of
map as a method that is lifting a function IntermediaryType => FinalType to a function Future[Intermediary] => Future[FinalType].If you have a
Future[Try[Type]], you can do a "double lifting" (I'm claiming the trademark on that term!):complicatedFunctionReturningFutureTry(input).map(_.map(mappingFunction))which lifts the same function
IntermediaryType => FinalType to a function Future[Try[Intermediary]] => Future[Try[FinalType]].Code Snippets
def getSomething(input: V): Future[FinalType] = {
val intermediate: IntermediaryType = complicatedFunctionReturningFuture(input)
mappingFunction(intermediate)
}complicatedFunctionReturningFuture(input).map(mappingFunction)complicatedFunctionReturningFutureTry(input).map(_.map(mappingFunction))Context
StackExchange Code Review Q#59477, answer score: 3
Revisions (0)
No revisions yet.