Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sorted predicates #630

Open
mhriemers opened this issue Apr 16, 2019 · 1 comment
Open

Sorted predicates #630

mhriemers opened this issue Apr 16, 2019 · 1 comment

Comments

@mhriemers
Copy link

mhriemers commented Apr 16, 2019

As discussed in #6, there is room for a Sorted predicate. I'm currently running into use cases where an algorithm's implementation differs for sorted and unsorted collections. If we can decide on a type signature, I can start with the implementation. With regards to the sort direction, in my opinion we can do two things:

  1. we can just assume ascending.
  2. we can provide some sort of enum type which describes the direction.

I'd like to hear opinions on this. Also, our implicit Validate will need some sort of (implicit) Ordering to decide if the collection is sorted or not.

@mhriemers mhriemers changed the title Sorted predicates Sorted predicates Apr 16, 2019
@mhriemers
Copy link
Author

mhriemers commented Apr 16, 2019

This what I could come-up with so far:

final case class Sorted[D <: SortDirection](d: D)
sealed trait SortDirection {
  def ascending: Boolean
}
implicit case object Ascending extends SortDirection {
  override def ascending: Boolean = true
}
implicit case object Descending extends SortDirection {
  override def ascending: Boolean = false
}
type Asc = Ascending.type
type Desc = Descending.type

object Sorted {
  implicit def sortedValidate[A, I[a] <: Iterable[a], D <: SortDirection](implicit
                                                                          d: D,
                                                                          ord: Ordering[A]): Validate.Plain[I[A], Sorted[D]] =
    Validate.fromPredicate(i  {
      val tuples = i.dropRight(1).zip(i.tail)
      val f = if (d.ascending) ord.lteq _ else ord.gteq _
      tuples.forall(f.tupled)
    }, i  {
      val tuples = i.dropRight(1).zip(i.tail)
      val sign = if (d.ascending) "<=" else ">="
      tuples.map {
        case (a, b)  s"$a $sign $b"
      }.mkString("(", " && ", ")")
    }, Sorted(d))
}

Let me know what you guys think. This could be more generalized to Traversable[A] but I didn't have time to figure that out yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant