3

I'm having some trouble with view bounds. I have written the following function, which should take any object seq viewable as a Seq[T] and return None if it is empty, or Some(seq) otherwise.

def noneIfEmpty[T, S <% Seq[T]](seq: S): Option[S] =
  if (seq.isEmpty) None else Some(seq)

Let's define the function...

scala> def noneIfEmpty[T, S <% Seq[T]](seq: S): Option[S] = ...
noneIfEmpty: [T, S](seq: S)(implicit evidence$1: S => scala.collection.immutable.Seq[T])Option[S]

Okay, the function signature looks right. Let's try an empty list...

scala> noneIfEmpty(List())
res54: Option[List[Nothing]] = None

So far so good. Now let's try a nonempty list...

scala> noneIfEmpty(List(1,2,3))
res55: Option[List[Int]] = Some(List(1, 2, 3))

Great. How about an Array?

scala> noneIfEmpty(Array())
<console>:15: error: No implicit view available from Array[Nothing] => scala.collection.immutable.Seq[Any].
              noneIfEmpty(Array())
                         ^

Not so great. What's going on here? Isn't there an implicit conversion from Array[T] to WrappedArray[T]? Shouldn't scala.Predef.wrapRefArray take care of this?

zh2l4d7s
  • 97
  • 1
  • 9

1 Answers1

3

Did you have import scala.collection.immutable.Seq somewhere?

There are series implicit view named *ArrayOps defined in scala.Predef which convert Array[T] to scala.collection.mutable.ArrayOps[T], but not immutable.Seq.

scala> def noneIfEmpty[S <% collection.Seq[_]](seq: S): Option[S] =
     |   if(seq.isEmpty) None else Some(seq)
noneIfEmpty: [S](seq: S)(implicit evidence$1: S => Seq[_])Option[S]

scala> noneIfEmpty(Array[Int]())
res0: Option[Array[Int]] = None

scala> noneIfEmpty(Array[Int](1, 2, 3))
res1: Option[Array[Int]] = Some([I@7c92fffb)
Eastsun
  • 18,526
  • 6
  • 57
  • 81