2012-06-03 89 views
3

現在我有許多參數可以是沒有,我想分配整個表達式默認值。斯卡拉:如何處理很多參數可以是無

現在我做這樣的事情

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") 
} 

,但它是一個有點太冗長。我想知道什麼是處理它更地道和優雅的方式,理想情況下是類似的信息(這是僞代碼,當然!):

val fullName = (name + ", " + surname).getOrElse("unknown") 

或類似的東西...

(只是避免雙重.getOrElse將是巨大的......)

回答

15

這個怎麼樣

scala> val fullName = (for(n <-name;s <-surname) yield n + s).getOrElse("unknown") 
fullName: String = unknown 
+2

desugared:'surname flatMap(x => name map(x +「,」+ _))getOrElse「unknown」' –

2

我發現這種方式:

val fullname = (name, surname) match { 
    case (Some(x), Some(y)) => x + ", " + y 
    case _ => "unknonw" 
} 

,但它仍然是一個有點冗長

13

您可能要有點了解應用性函子,因爲相同的模式可以在各種方式使用。使用scalaz,還有就是應用性建設者:

(name |@| surname)(_ + _) 

發生了什麼事是這樣的:

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

也就是說,功能f被提升到適用函子M的境界。這是特別有用的,因爲它與Option,Validation,Promise,List,Stream等等一起工作。也就是說,就像你可能會使用表達式:

(name |@| surname)(_ + _) 

其中namesurname都是Option[String],你可以切換他們是ValidationNEL[Exception, String]Promise[String]和代碼仍然會做同樣的事情(適合於高種類被使用)。這非常強大。

+0

@opensas這裏甚至是一個'Person'的例子:http:// applicative-errors-scala .googlecode.com/svn/artifacts/0.6/html/index.html HTH – AndreasScheinert