I want to use Scala's "monadic-for" to obtain, at the end, either Some(x) or None.
This means, that the first element in this monad has to be an Option.
The problem is, that sometimes I don't have an Option to start with.
So I "fake" one, using a dummy value.
The abstract form looks like this:
for {
// only used to yield Some/None at the end
dummyVal <- Some("dummy value")
// ...
// ... other monadic expressions
// ...
} yield {
// result which will be wrapped into Some(...)
}
A concrete example could be:
case class Person(name:String, age:Int)
val p = Person("John", 32)
At the end this evaluates to Some("John")
:
for {
dummy <- Some("dummy")
matchedPerson = p
if matchedPerson.age > 30
} yield {
matchedPerson.name
}
Whereas this evaluates to None
:
for {
dummy <- Some("dummy")
matchedPerson = p
if matchedPerson.age > 55
} yield {
matchedPerson.name
}
Though I get what I want (a monadic-for that evaluates to Option
), I have a bad feeling.I had to "misuse" the monadic-for by starting with a "dummy" Option
, just for the sake of getting Some
/None
at the end.
My question is: is there a better way to achieve this, without creating a dummy value?
UPDATE:
Consider this example, which builds on the one above:
case class Person(name: String, username: String, age: Int)
case class Session(loggedInPerson: Person)
def isValidUser(username: String):Boolean = ???
def isValidPassword(username: String, password: String):Boolean = ???
def readPassword():Option[String] = ???
val usr = Person("John Wayne", "jwayne", 55)
for {
dummy <- Some("does not matter")
username = usr.username
if isValidUser(username)
pass <- readPassword()
if isValidPassword(username, pass)
} yield {
Session(usr)
}
Now it's clear that the "for" is pretty long and probably not practicable to re-write using filters, flatMaps, etc.
My goal at the end is to get an Option[Session]
. I "force" the for to this outcome by starting with a dummy Some
value.
But as has been pointed out by Noel M
, I can just rewrite:
dummy <- Some("does not matter")
with:
usr <- Some(usr)