0

I have the following function :

 def getWayDepthFirst(maze: Maze, position: Position, way: List[Position]): List[List[Position]] = { if (!canWalkOnCell(maze, position)) { Nil } else { if (isExit(position, maze)) { List(position :: way) } else { val explorationArea: List[Position] = List(position.north, position.east, position.south, position.west) filter (x => !way.contains(x) && canWalkOnCell(maze, x)) if (explorationArea.size > 1) { val possibleWays: Future[List[List[List[Position]]]] = Future.traverse(explorationArea)(notYetVisitedPosition => Future(getWayDepthFirst(maze, notYetVisitedPosition, position :: way))) // possibleWays.onSucces() } else { explorationArea.flatMap { ( notYetVisitedPosition => getWayDepthFirst(maze, notYetVisitedPosition, position :: way)) } } } } 

It should find all the ways through a maze. If there are two or more possible ways that can be search then each of these should be handled in a future.

Now my problem is how to return the result of this. With the Future.traverse I end up with a Future[List[List[List[Position]]]] but what I need is a List[List[Position]].

What is a possibility to return the correct value? And where do I do this? In the onSuccess?

0

1 Answer 1

2

Zernike is correct in suggesting future.map(_.flatten), but this will give you Future[List[List[Position]]] and not List[List[Position]].

You are using Future.traverse to find possible ways in parallel, so you get a Future[...] as a result. You are suggesting to use onSuccess to return the List[List[Position]] from the Future, but with onSuccess you essentially register a callback function which will be executed when the Future ends successfully. Since the callback function will be executed independently of your getWayDepthFirst function, you can not return anything from inside this callback function.

The solution would be to change the result type of getWayDepthFirst to Future[List[List[Position]]].

This would look like this :

def getWayDepthFirst( maze: Maze, position: Position, way: List[Position] ): Future[List[List[Position]]] = if (! canWalkOnCell(maze, position)) { Future.successful(Nil) } else if (isExit(position, maze)) { Future.successful(List(position :: way)) } else { val positions = List(position.north, position.east, position.south, position.west) val explorationArea = positions filter (x => !way.contains(x) && canWalkOnCell(maze, x) ) Future.traverse(explorationArea)( notYetVisitedPosition => getWayDepthFirst(maze, notYetVisitedPosition, position :: way) ).map(_.flatten) } 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, so I would handle the onSuccess where I am calling this method the first time I guess. I still get an error with this though. type mismatch; found : scala.concurrent.Future[List[List[Position]]] required: scala.concurrent.Future[List[Position]] on this line getWayDepthFirst(maze, notYetVisitedPosition, position :: way)) ).map(_.flatten)
Seems that there was just on ) too much infront of map(_.flatten)
You are correct, I have removed the parenthesis from the code. You can find more information on working with Future on the Scala website
You can use scalaz's traverseM to replace the .traverse(...).map(_.flatten).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.