Я пытаюсь отфильтровать HList по литеральному типу, но не могу заставить его работать, он просто фильтрует все строки:
import shapeless._
import shapeless.ops.hlist._
def filterLabel[Labels <: HList, Label, Out <: HList](labels: Labels, label: Label)(
implicit sel: Filter.Aux[Labels, label.type, Out]): Out = sel(labels)
val a: "a" = "a"
val b: "b" = "b"
val c1: 1 = 1
val h1 = a :: b :: a :: c1 :: HNil
//result: hl: String :: String :: String :: Int :: HNil = "a" :: "b" :: "a" :: 1 :: HNil
//looks like literal-types are no longer present?
filterLabel(h1, "a")
Я проверял это с Scala org.typelevel 2.12.4-bin-typelevel-4.Это должно быть возможно?Должен ли HList поддерживать литеральные типы?
Код можно запустить в Scala с опцией компилятора "-Yliteral-types" для Scala 2.12.Например, аммонит:
curl -s https://raw.githubusercontent.com/typelevel/scala/typelevel-readme/try-typelevel-scala.sh | bash
repl.compiler.settings.YliteralTypes.value = true
import $ivy.`com.chuusai::shapeless:2.3.3`, shapeless._, shapeless.ops.hlist._
//now paste the above code
ОБНОВЛЕНИЕ: у меня теперь есть следующее для только Lightbend Scala:
import shapeless._
import shapeless.ops.hlist._
import syntax.singleton._
implicit def stringToF(label: String) = () => label.narrow
def filterLabel[Labels <: HList, T, Label <: String, Out <: HList](labels: Labels, label: () => Label)(
implicit
sel: Filter.Aux[Labels, Label, Out]): Out = sel(labels)
val h1 = "a".narrow :: "b".narrow :: "a".narrow :: "c".narrow :: HNil
filterLabel(h1, "a")
//res92: a :: a :: HNil = "a" :: "a" :: HNil
, он также работает со списком объектов с параметрами литерального типа:
import shapeless._
import shapeless.ops.hlist._
import syntax.singleton._
class MyLabel[L <: String](label: L)
object MyLabel {
def apply(label: String) = new MyLabel(label.narrow)
}
implicit def stringToMyLabel(label: String) = new MyLabel(label.narrow)
def filterLabel[Labels <: HList, T, Label <: String, Out <: HList](labels: Labels, label: MyLabel[Label])(
implicit
sel: Filter.Aux[Labels, MyLabel[Label], Out]): Out = sel(labels)
val h1 = MyLabel("a") :: MyLabel("b") :: MyLabel("a") :: MyLabel("c") :: HNil
filterLabel(h1, "a")
//res88: MyLabel[a] :: MyLabel[a] :: HNil = ammonite.$sess.cmd83$MyLabel@55a5d73c :: ammonite.$sess.cmd83$MyLabel@eb78e11 :: HNil