Reputation: 197
I'm trying to use an Either return type from my function to either get back an object or a string. In the case it is an object, I'd like to start calling methods from this object. In the case it is a string, I'd like to call some other functions elsewhere. I keep getting hung up because the thing being returned is not the object I'm returning, it is of type "left" and I can't seem to get that object out of the "Left" type back into the "Player" type I'd like. This is contained in an object that is extending the mutable queue. Here is my function which looks up the Player object in a Map based off the key which is in my ActionQueue object:
def popCurrentAction : Either[Player, String] = {
val currentAction = this.dequeue
this.enqueue(currentAction)
if (playerMap.get(currentAction) != None) {
Left((playerMap.get(currentAction).get))
}
else {
Right(currentAction)
}
}
Here is my function which is trying to use the function which returns Either a "Player" object or a String.
def doMove = {
var currentAction = ActionQueue.popCurrentAction
if (currentAction.isLeft) {
var currentPlayer = currentAction.left
var playerDecision = currentPlayer.solicitDecision() // This doesn't work
println(playerDecision)
}
else {
// Do the stuff if what's returned is a string.
}
}
I have tried using the .fold function, which does allow me to call the solicitDecision function and get what it returns, but I would like to use the Player object directly. Surely this is possible. Can someone help?
var currentPlayer = currentAction
var playerDecision = currentPlayer.fold(_.solicitDecision(), _.toString())
// This is close but doesn't give me the object I'm trying to get!
println(playerDecision)
Upvotes: 0
Views: 70
Reputation: 1276
The best way for making case distinctions and extracting things at the same time is to use a pattern match.
In your case, that would be roughly the following code:
def doMove = {
val currentAction = ActionQueue.popCurrentAction
currentAction match {
case Left(currentPlayer) =>
val playerDecision = currentPlayer.solicitDecision()
println(playerDecision)
case Right(string) =>
println(string)
}
}
Note also that I used val
instead of var
. When you have a variable that you are not planning to change, val
is better style (roughly speaking, it makes a read-only variable).
Upvotes: 2
Reputation: 51271
You haven't stated what error you're getting, just "this doesn't work", and the code you've posted isn't complete enough to be compiled and tested. What is the currentPlayer
type when the compiler fails it?
Having said that, you might consider refactoring your code.
def doMove = ActionQueue.popCurrentAction.fold(getDecision, stringStuff)
def getDecision(player: Player) = ....
def stringStuff(str: String) = ....
Upvotes: 2