In below example, I want to define a contains
method that doesn't compile if a
and b
are not of the same base type.
contains1
impl, if a
is Seq[Int]
and b is String
, T
is derived to be Any
, and it compiles. This is not I want.contains2
impl, if a
is Seq[Int]
and b is String
, then it doesn't compile. The behavior is what I want.def contains1[T](a: Seq[T], b: T): Boolean = a.contains(b)
println(contains1(Seq(1,2,3), "four")) // false
def contains2[T: Ordering](a: Seq[T], b: T): Boolean = a.contains(b)
println(contains2(Seq(1,2,3), "four")) // compilation error
// cmd7.sc:1: No implicit Ordering defined for Any.
// val res7 = isMatched(Seq(1,2,3), "s")
^
// Compilation Failed
However, is there a simpler way to achieve the same behaviour as in contains2
? Ordering
context bound confuses me as the method has nothing to do with sorting/ordering at all.
You could use generalized type constraints operator =:=
.
For example:
def contains[A,B](a: Seq[A], b: B)(implicit evidence: A =:= B): Boolean = a.contains(b)
and then:
println(contains1(Seq(1,2,3), "four")) //fails with Cannot prove that Int =:= String.
println(contains1(Seq("one"), "four")) //returns false
println(contains1(Seq("one", "four"), "four")) //true
More on generalized type constraints here and here.
As LuisMiguelMejíaSuárez noticed, you could also consider using B <:< A
instead of A =:= B
. I won't elaborate on differences between these two because it's described in linked answer and article, but in brief, <:<
would also allow all B
that are a subtype of A
, while =:=
needs types to match exactly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With