From 52a105d0d4e857943c4e1be10f99ccb3c1c5d5b1 Mon Sep 17 00:00:00 2001 From: Aristov Ivan Date: Thu, 27 Feb 2020 10:43:38 +0300 Subject: [PATCH 1/2] Optimize SelectRange typeclass derivation --- .../src/main/scala/shapeless/ops/hlists.scala | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/core/src/main/scala/shapeless/ops/hlists.scala b/core/src/main/scala/shapeless/ops/hlists.scala index 7113167e1..51dd0ab8b 100644 --- a/core/src/main/scala/shapeless/ops/hlists.scala +++ b/core/src/main/scala/shapeless/ops/hlists.scala @@ -916,10 +916,10 @@ 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 } @@ -929,12 +929,22 @@ object hlist { type Aux[L <: HList, A <: Nat, B <: Nat, Out0 <: HList] = SelectRange[L, A, B] {type Out = Out0} - 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) + } + + 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(l: L): Out = sel(l) + def apply(t: H :: L): select.Out = select(t.tail) } } From 43c1f3f8f485fab0bd685cd06ca36926c141844a Mon Sep 17 00:00:00 2001 From: Georgi Krastev Date: Sat, 24 Apr 2021 11:12:29 +0200 Subject: [PATCH 2/2] Bring back SelectRangeAux for binary compatibility --- .../src/main/scala/shapeless/ops/hlists.scala | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/core/src/main/scala/shapeless/ops/hlists.scala b/core/src/main/scala/shapeless/ops/hlists.scala index 51dd0ab8b..9b1646975 100644 --- a/core/src/main/scala/shapeless/ops/hlists.scala +++ b/core/src/main/scala/shapeless/ops/hlists.scala @@ -927,25 +927,31 @@ object 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 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) - } + ): Aux[L, _0, T, take.Out] = new SelectRange[L, _0, T] { + type Out = take.Out + def apply(t: L): take.Out = take(t) + } 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) - } + ): 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) + } }