The following doesn't work.
object Foo {
def union(s: Set[Int], t: Set[Int]): Set[Int] = t match {
case isEmpty => s
case (x:xs) => union(s + x, xs)
case _ => throw new Error("bad input")
}
}
error: not found: type xs
How can I pattern match over a set?
This is what I can come up with:
Well,
x:xs
meansx
of typexs
, so it wouldn't work. But, alas, you can't pattern match sets, because sets do not have a defined order. Or, more pragmatically, because there's no extractor onSet
.You can always define your own, though:
For example:
First of all, your
isEmpty
will catch everySet
since it's a variable in this context. Constants start with an upper case letter in Scala and are treated only as constants if this condition holds. So lowercase will assign anySet
toisEmpty
(were you looking forEmptySet
?)As seen here, it seems that pattern matching isn't very preferable for
Set
s. You should probably explicitly convert theSet
to aList
orSeq
(toList
/toSeq
)Set
is not acase class
and doesn't have aunapply
method.These two things imply that you cannot pattern match directly on a
Set
.(update: unless you define your own extractor for
Set
, as Daniel correctly shows in his answer)You should find an alternative, I'd suggest using a fold function
or, avoiding most explicit type annotation
or even shorter
This will accumulate the elements of
s
overt
, adding them one by onefolding
Here are the docs for the fold operation, if needed for reference:
Applies a binary operator to a start value and all elements of this set, going left to right.
Note: might return different results for different runs, unless the underlying collection type is ordered. or the operator is associative and commutative.