Skip to content

Commit

Permalink
Merge pull request #1129 from joroKr21/select-range
Browse files Browse the repository at this point in the history
Optimize SelectRange typeclass derivation
  • Loading branch information
joroKr21 authored Apr 24, 2021
2 parents bfc50fe + 43c1f3f commit 5d4443a
Showing 1 changed file with 26 additions and 10 deletions.
36 changes: 26 additions & 10 deletions core/src/main/scala/shapeless/ops/hlists.scala
Original file line number Diff line number Diff line change
Expand Up @@ -916,26 +916,42 @@ object hlist {
}

/**
* Type class supporting supporting access to the elements in range [a,b[ of this `HList`.
* Avaialable only if this `HList` contains all elements in range
* Type class supporting supporting access to the elements in range [a,b] of this `HList`.
* Available only if this `HList` contains all elements in range
*
* @author Andreas Koestler
* @author Ivan Aristov
*/
@implicitNotFound("Implicit not found: shapeless.Ops.SelectRange[${L}, ${A}, ${B}]. You requested the elements in range [${A},${B}[, but HList ${L} does not contain all of them.")
trait SelectRange[L <: HList, A <: Nat, B <: Nat] extends DepFn1[L] { type Out <: HList }

object SelectRange {
def apply[L <: HList, A <: Nat, B <: Nat](implicit sel: SelectRange[L, A, B]): Aux[L, A, B, sel.Out] = sel

type Aux[L <: HList, A <: Nat, B <: Nat, Out0 <: HList] = SelectRange[L, A, B] {type Out = Out0}
type Aux[L <: HList, A <: Nat, B <: Nat, Out0 <: HList] = SelectRange[L, A, B] {
type Out = Out0
}

@deprecated("Slower version of take and drop", "2.3.5")
def SelectRangeAux[L <: HList, A <: Nat, B <: Nat, Ids <: HList, SelOut <: HList](
implicit range: nat.Range.Aux[A, B, Ids], sel: SelectMany.Aux[L, Ids, SelOut]
): Aux[L, A, B, SelOut] = new SelectRange[L, A, B] {
type Out = SelOut
def apply(l: L): Out = sel(l)
}

implicit def SelectRangeAux[L <: HList, A <: Nat, B <: Nat, Ids <: HList, SelOut <: HList]
(implicit range: shapeless.ops.nat.Range.Aux[A, B, Ids], sel: SelectMany.Aux[L, Ids, SelOut]): Aux[L, A, B, SelOut] =
new SelectRange[L, A, B] {
type Out = SelOut
implicit def take[L <: HList, T <: Nat](
implicit take: Take[L, T]
): Aux[L, _0, T, take.Out] = new SelectRange[L, _0, T] {
type Out = take.Out
def apply(t: L): take.Out = take(t)
}

def apply(l: L): Out = sel(l)
}
implicit def drop[H, L <: HList, A <: Nat, B <: Nat](
implicit select: SelectRange[L, A, B]
): Aux[H :: L, Succ[A], Succ[B], select.Out] = new SelectRange[H :: L, Succ[A], Succ[B]] {
type Out = select.Out
def apply(t: H :: L): select.Out = select(t.tail)
}
}


Expand Down

0 comments on commit 5d4443a

Please sign in to comment.