内部理解的选项行为是Scala



两个新手问题。

看来for理解知道Options,并且可以自动跳过None和UNWRAP Some,例如。

val x = Map("a" -> List(1,2,3), "b" -> List(4,5,6), "c" -> List(7,8,9))
val r = for {map_key <- List("WRONG_KEY", "a", "b", "c")
             map_value <- x get map_key } yield map_value

输出:

r: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))

Options去哪儿?有人可以阐明这项工作吗?我们可以始终依靠这种行为吗?

第二件事是为什么它不编译?

val x = Map("a" -> List(1,2,3), "b" -> List(4,5,6), "c" -> List(7,8,9))
val r = for {map_key <- List("WRONG_KEY", "a", "b", "c")
                 map_value <- x get map_key
                 list_value <- map_value
    } yield list_value

它给出

Error:(57, 26) type mismatch;
 found   : List[Int]
 required: Option[?]
             list_value <- map_value
                        ^

查看第一个示例的类型,我不确定为什么我们需要在这里有一个Option

用于综合的

将转换为呼叫,以呼叫以MAP或FLATMAP调用的顺序。请参阅此处

您的for环相当于

List("WRONG_KEY", "a", "b", "c").flatMap(
  map_key => x.get(map_key).flatMap(map_value => map_value)
)

Option中的flatMap定义为

 @inline final def flatMap[B](f: A => Option[B]): Option[B]

因此,由于编译器通知您,因此不允许将List作为参数传递。

我认为区别是由于综合的方式扩展到seq特征中的映射((和flatmap方法调用。

为了简洁,让我们定义一些变量:

var keys = List("WRONG_KEY", a, b, c)

您的第一种情况等效于:

val r = keys.flatMap(x.get(_))

您的第二种情况相当于:

val r= keys.flatMap(x.get(_).flatMap{ case y => y })

我认为问题是该option.flatmap((应该返回一个选项[],在第一种情况下很好,但在第二种情况下与x.get((。flatmap传递的内容不一致,这是列表[int]。

Wampler&amp;Payne。

也许这种很小的差异,设置括号并弄平了,使其清晰:

val r = for {map_key <- List("WRONG_KEY", "a", "b", "c")
     |             } yield x get map_key 
r: List[Option[List[Int]]] = List(None, Some(List(1, 2, 3)), Some(List(4, 5, 6)), Some(List(7, 8, 9)))
val r = (for {map_key <- List("WRONG_KEY", "a", "b", "c")
     |             } yield x get map_key).flatten 
r: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))

那等同于:

scala> List("WRONG_KEY", "a", "b", "c").map (x get _)
res81: List[Option[List[Int]]] = List(None, Some(List(1, 2, 3)), Some(List(4, 5, 6)), Some(List(7, 8, 9)))
scala> List("WRONG_KEY", "a", "b", "c").map (x get _).flatten
res82: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))

中间值(map_key(在第二块中消失了。

您正在将两个不同的单子(ListOption(混合在供语句中。这有时可以按预期工作,但并非总是如此。无论如何,您都可以自己列入列表:

for {
  map_key <- List("WRONG_KEY", "a", "b", "c")
  list_value <- x get map_key getOrElse Nil 
} yield list_value

最新更新