shapeless: Generic programming for Scala | This room deprecated in favour of #shapeless on the Typelevel Discord: https://discord.gg/bSQBZA3Ced
milessabin on 2.3
Use Scala Native JUnit plugin Bump Scala Native version Merge pull request #1259 from a… (compare)
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)
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.
A -> B
and A -> C
then by definition it's not a mapping
A ->
map to, at the type level?
B
or C
?