Хабр Курсы для бэкендеров
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Эмуляция Higher-Kinded Types
Жесть из мира scala
Это способ написать функцию, которая работает с разными "контейнерами" (vec, option,...) одинаково. Можно реализовать свой вариант map, например...
Вот нашёл, вроде как аналог
Весь тот «шаманский» кусок Rust – это на самом деле не что иное, как «drop N элементов у H-списка». Н-список это гетерогенный список.
В Scala (с Shapeless) это уже реализовано из коробки тип-классом shapeless.ops.hlist.Drop, поэтому прямой перевод занимает буквально несколько строк
SliceFrom
// build.sbt
// libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.10"
import shapeless._
import shapeless.ops.hlist.Drop
import shapeless.nat._ // готовые Nat-константы _0, _1, _2 …
/** ---------------------------------------------------------------------------
* Extension-метод, полностью эквивалентный вашему `ListIndex<RangeFrom<N>>`.
* Никакой ручной рекурсии – всё делает готовый HKT Drop.
* ------------------------------------------------------------------------- */
object syntax {
implicit final class SliceFrom[L <: HList](private val l: L) extends AnyVal {
/** «Срез от N-го и до конца» (RangeFrom<N>) */
def sliceFrom[N <: Nat](implicit drop: Drop.Aux[L, N, Out], ev: Out <:< HList)
: Out = drop(l)
type Out <: HList
}
}
import syntax._ // подключаем «сахар»
/* ========================= DEMO ========================= */
// Гетерогенный список как у вас (Int, Boolean, String)
val hlist = 42 :: true :: "hi" :: HNil
// 0.. == целый список
val whole = hlist.sliceFrom[_0] // Int :: Boolean :: String :: HNil
// 1.. == хвост без первого
val tail1 = hlist.sliceFrom[_1] // Boolean :: String :: HNil
// 2..
val tail2 = hlist.sliceFrom[_2] // String :: HNil
println(whole) // 42 :: true :: hi :: HNil
println(tail1) // true :: hi :: HNil
println(tail2) // hi :: HNil
Сорцы на выходные на «расте»