Scala:如何处理许多可以是None的参数

ope*_*sas 3 scala optional-parameters option

现在我有很多可以没有的参数,我想将整个表达式赋值为默认值.

现在我正在做的事情

var name: Option[String] = None
var surname: Option[String] = Some("Smith")

val fullName:String = {
  name.map { name => 
    surname.map { surname => 
      surname + ", " + name
    }.getOrElse("unknown")
  }.getOrElse("unknown")
}
Run Code Online (Sandbox Code Playgroud)

但它有点太冗长了.我想知道什么是更惯用和更优雅的方式来处理它,理想情况下它会像(它的伪代码,当然!):

val fullName = (name + ", " + surname).getOrElse("unknown")
Run Code Online (Sandbox Code Playgroud)

或类似的东西......

(只是避免双重.getOrElse会很棒......)

Eas*_*sun 15

这个怎么样

scala> val fullName = (for(n <-name;s <-surname) yield n + s).getOrElse("unknown")  
fullName: String = unknown
Run Code Online (Sandbox Code Playgroud)

  • desugared:`surname flatMap(x => name map(x +","+ _))getOrElse"unknown"` (2认同)

oxb*_*kes 13

您可能想要了解一些关于applicative仿函数的知识,因为可以以各种方式使用相同的模式.使用scalaz,有一个应用程序构建器:

(name |@| surname)(_ + _)
Run Code Online (Sandbox Code Playgroud)

这是怎么回事:

(M[A] |@| M[B])(fabc) ~> M[C] //fabc is a function f: (A, B) => C
Run Code Online (Sandbox Code Playgroud)

也就是说,该功能f正被提升到应用仿函数的领域M.这是特别有用,因为它的工作原理Option,Validation,Promise,List,Stream等等.也就是说,就像你可以使用表达式一样:

(name |@| surname)(_ + _)
Run Code Online (Sandbox Code Playgroud)

在哪里name和哪surname两个Option[String],你可以将它们切换为ValidationNEL[Exception, String]或者Promise[String]代码仍然会做同样的事情(适合使用的更高类型).这非常强大.