I tried to define a function that would check whether a generic Seq is sorted.
I came up with this:
import Ordering.Implicits._
def isOrdered[A: Ordering](seq: Seq[A]): Boolean =
seq.sliding(2).map({ case List(a, b) => b > a }).forall(identity)
At which point, the compiler throws back "No implicit Ordering defined for A".
I can work around this by ascribing a and b as follows:
def isOrdered[A: Ordering](seq: Seq[A]): Boolean =
seq.sliding(2).map({ case List(a: A, b: A) => a < b }).forall(identity)
At which point the compiler happily accepts the function.
What I find curious is that the following implementation works out of the box:
def isOrdered[A: Ordering](seq: Seq[A]): Boolean =
seq.sliding(2).exists{s => s(0) > s(1)}
Where as far as I can tell, the only significant difference is that I don't use a partial function.
Can anyone explain this behavior?
In the first case,
This doesn't work because you have just defined a partial function but not the Ordering of those elements. In the sense
case List(a,b)
represents a List containinga
andb
. Nowa
can mean anything.Doinga:A, b:A
works because now you define that it is a List containing 2 elements of typeA
.And because we have defined Ordering for
A
. Hence the second works.As per the third one:
seq.sliding(2).
returns aIterator[List[A]]
. For eachList[A]
in the iterator, you are callings(0) > s(1)
. Heres(0)
ands(1)
is of typeA
. Because you have defined the boundA: Ordering
, you have ordering defined for typeA
. In this cases(0) s(1)
. Hence it works.