Monad 变换用于理解
考虑一下:
def xs(c: String): Option[List[Long]] = ...
val ys: Stream[Long] = ...
现在我会编写一个类似以下的方法:
def method(oc: Option[String]): Option[Long] = for {
c <- oc
list <- xs(c)
} yield{
for {
first <- ys.find(list contains _)
} yield first
}
但是这当然不会编译,因为推断的类型是 Option[Option[Long]]。
在scala语法和标准库方面有没有办法获得Option[Long]?我知道我可以进行模式匹配,但是是否可以使用理解来完成它的问题才刚刚出现。
感谢 tenshi 的回答,这完成了工作,但是我刚刚遇到了问题的另一个例子:
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)
}
我可以在 for 中添加 a
作为: a <- Some(A(c ))
但是隐式的呢?这是否意味着我的代码的设计发生了变化?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为什么要使用 2 个嵌套的
for
理解?难道不应该有人做这项工作吗?更新
关于您的第二个示例。您可以在其他地方定义隐式并导入它或在方法的开头定义它,但我想您希望使其范围尽可能窄。在这种情况下,您可以直接在
for
理解中使用 block:或(可能是最简单的)显式提供隐式参数:
Why are you using 2 nested
for
comprehensions? Shouldn't one do the job?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:or (probably the simplest) provide implicit parameter explicitly: