Ian
Ian

Reputation: 1304

Combining wrapped elements in Scala: Option[Array[Int]]

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

Answers (3)

Samar
Samar

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

jwvh
jwvh

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

Bergi
Bergi

Reputation: 664297

You should be able to do

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

Upvotes: 0

Related Questions