Вопрос

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 

Update

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 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top