2009-08-07 5 views
14

Was ich suche ist diese Funktion:Gibt es etwas wie Haskells "Vielleicht" -Funktion in Scala?

def maybe[A, B](a: Option[A])(f: A => B)(g:() => B): B = a match 
{ 
    case Some(x) => f(x) 
    case None => g() 
} 

Es ist in der Haskell Vorspiel ist so ich denke, es irgendwo in der Scala-Standardbibliothek sein könnte und ich habe es nur knapp verfehlt. Ich hasse es, es in Projekten zu rekodieren, also frage ich mich, ob jemand weiß, wo es ist, oder ob es definitiv nicht da ist. Oder gibt es eine bessere Methode, um diese Funktionalität zu erhalten?

Antwort

14

könnten Sie

tun
val opt:Option[A] = // ... 
val result:B = opt.map(f).getOrElse(g()); 

getOrElse einen Parameter für-Namen hat, wird so g nur, wenn optNone ausgewertet werden.

+4

Warum 'a => f (a)' statt nur 'f'? –

+1

Nun, eigentlich sollte nur f funktionieren. –

0

Ich glaube nicht, dass es. Das Beste, was ich tun konnte, ist zu Kette Option des „map“ und „getOrElse“ zusammen:

scala> var a: Option[String] = Some("hello") 
a: Option[String] = Some(hello) 

scala> a.map(_.toUpperCase).getOrElse("empty") 
res19: java.lang.String = HELLO 

scala> a = None 
a: Option[String] = None 

scala> a.map(_.toUpperCase).getOrElse("empty") 
res21: java.lang.String = empty 
0

Ich glaube nicht da ist. Allerdings würde ich, schreiben Sie es g von Namen zu nehmen:

def maybe[A, B](a: Option[A])(f: A => B)(g: => B): B = a.map(f).getOrElse(g) 

Das ist mehr Scala- und Haskell-like und ein bisschen schöner zu verwenden.

16

Andere Antworten haben die map + getOrElse Zusammensetzung gegeben. Nur für das Protokoll, können Sie „hinzufügen“, um eine maybe Funktion Option auf folgende Weise:

implicit def optionWithMaybe[A](opt: Option[A]) = new { 
    def maybe[B](f: A=>B)(g: =>B) = opt map f getOrElse g 
} 

Es ist erwähnenswert, dass die Syntax von Funktionen höherer Ordnung in Scala ist in der Regel schöner, wenn der Funktionsparameter kommt zuletzt. Somit ist eine bessere Art und Weise maybe wäre zu organisieren, wie folgt:

def maybe[B](g: =>B)(f: A=>B) = opt map f getOrElse g 

Dies verwendet werden könnten, wie folgt:

val opt: Option[String] = ... 
opt.maybe("") { _.toUpperCase } 
4

Die Methode Falte genannt würde, wenn es Konvention einzuhalten waren (siehe Entweder .fold ist der Katamorphismus für Entweder).

4

können Sie verwenden scalaz, und dann haben Sie eine implizite Konvertierung in OptionW die fold hat, oder können Sie Scala 2.10.0-M3 verwenden und die eingebaute Option.fold

scala> Some(1).fold(5)(_ * 2) 
res5: Int = 2 

scala> (None: Option[Int]).fold(5)(_ * 2) 
res7: Int = 5 

Hinweis verwenden, dass die scalaz Unterschrift falten ist fold[X](some: A => X, none: => X), während das eingebaute scheint fold[X](none: => X)(some: A => X) zu sein.

+0

+1 für Erwähnung, dass die Funktion bereits in der Standardbibliothek in der neuesten Version ist – gerferra

0

würde ich Option.fold für diesen Einsatz:

opt.fold(g)(f) 

Beachten Sie, dass g by-Name ist, wie getOrElse. Beachten Sie auch die Inversion der Fälle.

Verwandte Themen