shapeless: Generic programming for Scala | This room deprecated in favour of #shapeless on the Typelevel Discord: https://discord.gg/bSQBZA3Ced
joroKr21 on main
Update sbt-mima-plugin to 1.1.0 Merge pull request #1258 from s… (compare)
joroKr21 on main
Update sbt-scalajs, scalajs-com… Merge pull request #1257 from s… (compare)
joroKr21 on v2.3.9
joroKr21 on 2.3
When case class has custom unap… Merge pull request #1256 from j… (compare)
joroKr21 on main
When case class has custom unap… Merge pull request #1255 from j… (compare)
HList
animalHandling
gives me a compiler error stating that there aren't any values of A
in my HList
, which makes sense I suppose.
type astronaut guide to Shapeless
import shapeless.ops.hlist.Selector
import shapeless.{::, HNil}
object Program {
case class Cat(name: String)
case class Dog(name: String)
case class Fish(name: String)
val animals = Cat("silver") :: Dog("daisy") :: Fish("nemo") :: HNil
def main(args: Array[String]): Unit = {
animalHandling(catNoise)
}
def catNoise(c: Cat): Unit = println("meow")
def animalHandling[A,B](f: A => B)(implicit ev: Selector[Cat :: Dog :: Fish :: HNil,A]): B = f(animals.select[A])
}
import shapeless.ops.hlist.Selector
import shapeless.{::, HList, HNil}
object Program {
case class Cat(name: String)
case class Dog(name: String)
case class Fish(name: String)
val animals = Cat("silver") :: Dog("daisy") :: Fish("nemo") :: HNil
def main(args: Array[String]): Unit = {
animalHandling(catNoise)(animals)
}
def catNoise(c: Cat): Unit = println("meow")
def animalHandling[A,B, H <: HList](f: A => B)(xs: H)(implicit ev: Selector[H,A]): B = f(xs.select[A])
}
Coproduct
and a given Seq
, the Seq
contains at least one element of every member in the Coproduct
. Currently, it's using union.Keys
and ops.hlist.ToTraversable
to string compare the symbols to the class SimpleNames. It feels like there should be a better way of doing this. Is there a more correct/canonical approach to solving that problem?
def check[A, C <: Coproduct, K <: HList](data: Seq[A])(
implicit
gen: LabelledGeneric.Aux[A,C]
keys: ops.union.Keys.Aux[C,K]
toList: ops.hlist.ToTraversable.Aux[K,List,Symbol]
): List[(String,Boolean)] = {
val classes: List[Symbol] = toList(keys())
classes.map(sym => (sym.name, data.exists(_.getClass.getSimpleName == sym.name)))
}
Int
-> Double
and Int
-> String
. Is this correct? Or am I using the library incorrectly?
Rel[Int, Double]
and Rel[Int, String]
, and you do get(1)
, how will the typesystem know whether the value is of type Double
or String
?
vault
library for a similar abstraction with different constraints
Key[A]
, and then you can get the corresponding value
implicit ev: SelectAll[H,I]
to ensure all members of I
are in H
.
implicit ev: IsHCons[I]
to ensure that I
is not empty.
def foo[H <: Hlist, I <: HList](xs: H, ys: I)(implicit ev: SelectAll[H,I], ev2: IsHCons[I]): Unit = {
println(xs.select[ev2.H])
}
ev2.H
is in H
.
SelectAll
does not guarantee order, so SelectAll[H, I]
does not provide proof that IsHCons[I]
is equal to IsHCons[H]
.
ev2.head(xs)
because while they have the same types, it’s not given that the head of H
is the same type as head of I
. It could be a type not existing in I
, or one of the types in the tail of I
. And if you wanna do xs.select
, you need to provide a Selector
instance for it.