2016-08-31 2 views
3

Ich versuche zu Arrays zu verbinden, die in einem Option gewickelt werden:gewickelte Elemente in Scala Kombination: Option [Array [Int]]

val a = Option(Array(1, 2, 3)) 
val b = Option(Array(4,5)) 
val q = for { 
    x <- a 
    y <- b 
} yield x ++ y 

Das Problem ist, dass, wenn bNone ist es kehrt None sogar obwohl ich gerne a haben würde. Und wenn aNone ist, beschwert sich der Compiler, dass ++ kein Mitglied von Nothing ist (obwohl ich erwarte, b zu erhalten). Ist das mit der Standardbibliothek machbar oder muss ich Halbgruppen in Cats oder Scalaz betrachten?

habe ich versucht, die folgende in Katzen, konnte es aber nicht funktionieren:

Semigroup[Option[Array[Int]]].combine(a,b) // === a |+| b 

Es sagt mir, dass:

could not find implicit value for parameter ev: cats.kernel.Semigroup[Option[Array[Int]]] 

Der resultierende Typ die gleichen wie die Typen von a sein sollte und b.

+0

ich versuchte mit a ++ b direkt in repl und es funktionierte für beide Fälle, d. H. A = keine oder b = keine. – Samar

Antwort

2

Erhaltung der Art Option[C[X]] tun können, wo C einige Kollektionstyp ist und X ist der Elementtyp dieser Sammlung, kam ich mit:

a.fold(b)(x => b.fold(a)(y => Option(x ++ y))) 
+0

Ich habe den Rückgabetyp hinzugefügt: im Grunde das gleiche wie a und b. – Ian

0

Sie sollten

val q = a.toList.flatten ++ b.toList.flatten 
+3

(a ++ b) .flatten funktioniert auch. – Samar

3
(a ++ b).flatten.toArray 

Die ++ - Methode ist kein Teil der Option-Klasse, aber sie funktioniert hier wegen einer impliziten Konvertierung. Wenn Sie die scala doc for Option sehen, heißt es This member is added by an implicit conversion from Option[A] to Iterable[A] performed by method option2Iterable in scala.Option.

So können Optionen als iterables behandelt werden.