type inference and for expression in scala
This works
val keys Option[List[Option[String]]] = someFunctionThatReturnsKeys()
val tries = for (
unwrapped <- keys) {
for(keyOption <- unwrapped;
stripped <- keyOption if stripped.contains(":"))
yield Try(java.lang.Long.parseLong(stripped.substring(stripped.lastIndexOf(":") + 1))) }
This does not work.
val tries = for (
unwrapped <- keys;
keyOption <- unwrapped;
stripped <- keyOption if stripped.contains(":"))
yield Try(java.lang.Long.parseLong(stripped.substring(stripped.lastIndexOf(":") + 1)))
The error is for the line
keyOption <- unwrapped;
The error is displayed as
type mismatch; found : List[scala.util.Try[Long]] required: Option[?]
I am using eclipse ide with scala 2.10
Why is the type inference failing?
Type inference isn't failing, it's that the for
desugars into a flatMap
, and Option
doesn't know how to flatten anything but another Option
.
What do you want the return type to be? That will determine what you actually want to do. For instance, if you want a list:
val tries = for {
unwrapped <- keys.toList;
keyOption <- unwrapped;
stripped <- keyOption if stripped.contains(":")
} yield Try(stripped.substring(1 + stripped.lastIndexOf(":")).toLong)
will do the trick. You'll get a List[Try[Long]]
, which will be empty if the outer Option
was None
.
If you want to keep the outer option, you really want a map
not a flatMap
at the outside, which is more easily written like so:
val tries2 = keys.map(unwrapped => for {
keyOption <- unwrapped;
stripped <- keyOption if stripped.contains(":")
} yield Try(stripped.substring(1 + stripped.lastIndexOf(":")).toLong))
This will give you an Option[List[Try[Long]]]
.
上一篇: 推断列表类型与任一和选项
下一篇: 类型推断和scala中的表达式