Consider:
def xs(c: String): Option[List[Long]] = ...
val ys: Stream[Long] = ...
Now I'd write a method something like:
def method(oc: Option[String]): Option[Long] = for {
c <- oc
list <- xs(c)
} yield{
for {
first <- ys.find(list contains _)
} yield first
}
but of course this doesn't compile, since the inferred type is Option[Option[Long]].
Is there a way in terms of scala syntax and standard library to get an Option[Long]? I know I can pattern match, but the question if it can be done using for comprehensions only just arised.
Thanks to tenshi for the answer, that does the job, however I just encountered another example of my problem:
class T
class U
class A(t: String)(implicit x: T)
def getU(a: A): Option[U] = ...
def getU_2(oc: Option[String]): Option[U] = for{
c <- oc
} yield{
implicit val someImplicit: T = new T
val a = A(c)
getU(a)
}
I can add a
in the for as: a <- Some(A(c))
but what about the implicit? Should that imply a design change in my code?
Why are you using 2 nested for
comprehensions? Shouldn't one do the job?
def method(oc: Option[String]): Option[Long] =
for {
c <- oc
list <- xs(c)
first <- ys.find(list contains _)
} yield first
About your second example. You can define implicit elsewhere and import it or define it in the beginning of the method, but I guess you want to make it's scope as narrow as possible. In this case you can use block directly in the for
comprehension:
def getU_2(oc: Option[String]): Option[U] = for {
c <- oc
a <- {
implicit val someImplicit: T = new T
getU(new A(c))
}
} yield a
or (probably the simplest) provide implicit parameter explicitly:
def getU_2(oc: Option[String]): Option[U] = for {
c <- oc
a <- getU(new A(c)(new T))
} yield a