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 containingaandb. Nowacan mean anything.Doinga:A, b:Aworks 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.