避免正确检查空值

时间:2014-01-19 11:29:45

标签: scala for-loop null nullpointerexception monads

我正在尝试构建gen​​eraziled for循环。 func1,func2,func3等每个函数都可能返回Some或None。

def func1(in: Option[String]): Option[String] = {
  return in
}

def func2(in: Option[String]): Option[String] = {
  return in
}

def func3(in: Option[String]): Option[String] = {
  return in
}


val res = for {
  x <- List(Some("hello"), None, Some("world"))
  y <- func1(x)
  z <- func2(y)
  w <- func3(z)
} yield w

print(res)

目的是完全避免空检查。

但是以下错误不允许我将参数传递给第一个调用

 found   : String
 required: Option[String]
  z <- func2(y)
             ^
one error found
  1. 建立这样的链的正确方法是什么?

  2. 如何避免在我的函数中保留Option [String]参数。我想用String直接操作。

2 个答案:

答案 0 :(得分:3)

Option trait aka Maybe Monad倾向于使用x => Option[y]类型的函数。编译器将for( <- ) yield语法糖替换为相应的flatMap调用,这相当于monadic bind运算符。

因此,您需要在X => M[Y]中使用flatMap等函数,并在List s \ Option s \ Stream s \ {{中使用for-expression 1}}等等。

了解更多here

此外,您的第一个表达式的类型为Iterator。要正确提取值,您可以使用Vladimir's answer中的中间值。

List[Option[X]]

答案 1 :(得分:0)

错误确切地说 - 您不需要funcX参数为Option[String]。仅使用String

def func1(in: String): Option[String] = {
  Some(in)
}

def func2(in: String): Option[String] = {
  Some(in)
}

def func3(in: String): Option[String] = {
  Some(in)
}


val res = for {
  x <- List(Some("hello"), None, Some("world"))
  y <- func1(x)
  z <- func2(y)
  w <- func3(z)
} yield w

print(res)