Reputation: 1304
I'm trying to combine to arrays that are wrapped in an Option
:
val a = Option(Array(1, 2, 3))
val b = Option(Array(4,5))
val q = for {
x <- a
y <- b
} yield x ++ y
The problem is that if b
is None
it returns None
even though I'd like to have a
. And if a
is None
the compiler complains that ++
is not a member of Nothing
(even though I expect to receive b
). Is this doable with the standard library or do I have to look at semigroups in Cats or Scalaz?
I tried the following in Cats but couldn't get it to work:
Semigroup[Option[Array[Int]]].combine(a,b) // === a |+| b
It tells me that:
could not find implicit value for parameter ev: cats.kernel.Semigroup[Option[Array[Int]]]
The resulting type should be the same as the types of a
and b
.
Upvotes: 3
Views: 542
Reputation: 2101
(a ++ b).flatten.toArray
The ++ method is not a part of the Option class, but it works here because of an implicit conversion. If you see the scala doc for Option, it says This member is added by an implicit conversion from Option[A] to Iterable[A] performed by method option2Iterable in scala.Option.
So, options can be treated as iterables.
Upvotes: 3
Reputation: 51271
Preserving the type Option[C[X]]
, where C
is some collection type and X
is the element type of that collection, I came up with:
a.fold(b)(x => b.fold(a)(y => Option(x ++ y)))
Upvotes: 2
Reputation: 664297
You should be able to do
val q = a.toList.flatten ++ b.toList.flatten
Upvotes: 0