Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 11:48
  • 11:38
  • 11:25
    codecov-io commented #803
  • 11:25
    joroKr21 synchronize #803
  • 11:16
    codecov-io commented #798
  • 11:16
    joroKr21 synchronize #798
  • 10:48
    Travis milessabin/shapeless (master) passed (2683)
  • 10:25

    milessabin on master

    Fix Typeable.describe for symbo… Merge pull request #945 from jo… (compare)

  • 10:25
    milessabin closed #945
  • 10:25
    milessabin closed #944
  • 10:25
    milessabin commented #945
  • Dec 08 19:26
  • Dec 08 19:03
    joroKr21 edited #945
  • Dec 08 19:03
    joroKr21 opened #945
  • Dec 08 15:59
    milessabin closed #942
  • Dec 08 15:54
    ashleymercer commented #942
  • Dec 08 15:48
    milessabin commented #943
  • Dec 08 15:45
    milessabin commented #942
  • Dec 08 15:14
    joroKr21 commented #942
  • Dec 08 15:13
    joroKr21 commented #942
Guangwen Zhou
@guangwenz
or foo(Person(“Foo”.some, None)) to get ”Foo” :: HNil
Paul Snively
@paul-snively
@guangwenz: OK. I believe you're on the right track. You'll at least need to use UnaryTCConstraint to express the fact that all of your HList elements are in Option.
Guangwen Zhou
@guangwenz
let me try that.
Guangwen Zhou
@guangwenz
Same compile error

  final case class Person(name: Option[String], age: Option[Int])

  def foo[R <: HList, V <: HList: UnaryTCConstraint.*->*[Option]#λ](
      person: Person
  )(implicit gen: LabelledGeneric.Aux[Person, R], values: Values.Aux[R, V]) = {
    val v: V = values(gen.to(person))
    object combine extends Poly2 {
      implicit def default[Acc <: HList, A] = at { (acc: Acc, r: Option[A]) =>
        r match {
          case None        => acc
          case Some(value) => value :: acc
        }
      }
    }
    v.foldLeft(HNil)(combine)
  }
Paul Snively
@paul-snively
I would imagine the constraint needs to be applied to the Values.Aux instances values.
But I'm not positive.
I would try to strip this down, maybe by starting from the "folder" example in the Shapeless distribution, then elaborating it to fold over an HList of Options, then adding the machinery to get that HList of Options from a case class via LabelledGeneric.
Fabio Labella
@SystemFw
@guangwenz what you want to do is impossible (with those types)
the generic type of Person is Option[String] :: Option[Int] :: HNil
and you want to get a type of either String :: HNil or Int :: HNil or String :: Int :: HNil depending on whether the Option is Some or None, so based on the class of those values, not their types
in other words, you want to know at compile time (in the type of the HList) things that you will only know at runtime (whether that given Option is Some or None)
Paul Snively
@paul-snively
Yeah, I was getting there slowly, too...
Guangwen Zhou
@guangwenz
Hmm. make sense to me, also a hard part for me to draw a line between this compile time vs run time .
thanks guys !
Paul Snively
@paul-snively
You'll need, at least, a Coproduct of HLists.
Sure. But don't despair yet. Shapeless is very good at "sum of product" representations. In fact, they're pretty central to what Shapeless is.
Guangwen Zhou
@guangwenz
good to know.
Paul Snively
@paul-snively
That said, a case class with all fields Options seems questionable to me in the first place, honestly.
What on earth would Person(None, None, None...) mean?
Guangwen Zhou
@guangwenz
That would be end with F.raiseError(SomeException(“invalid data”))
Paul Snively
@paul-snively
I'd strive to disallow it at compile time, if it's illegal.
"Make illegal states unrepresentable."
If it doesn't make sense for all fields to be None, I'd suggest a case class with all fields Options isn't the appropriate type.
Guangwen Zhou
@guangwenz
yes
Fabio Labella
@SystemFw
actually that can be pretty useful
altough I generally go with Thing[F[_]](a: F[String], b: F[Int])
and then you can go with kittens from Thing[Option] to Option[Thing[Id]]
Paul Snively
@paul-snively
I think the use-case is fine. I just question that representation.
Fabio Labella
@SystemFw
and in turn that can be used for several things (I often used for data type "patches", in various forms)
Paul Snively
@paul-snively
Right. If the goal is representational transformation like case class conversion, there are several good libraries for that.
Szilard Kovacs
@kovszilard

Hello,
I'm trying to develop a library to read case classes from environment variables.
Given the case class Foo(num: Int) and the env val NUM=42
the following method returns:

def readFromEnv[A](implicit envReader: EnvReader[A]): envReader.Out = envReader.readEnv
readFromEnv[Foo]
42 :: HNil

Now in order to turn this HList back to its original case class I come up with the following:

def readFromEnv2[A, O](implicit envReader: EnvReader.Aux[A, O], gen: Generic.Aux[A, O]): A = gen.from(readFromEnv[A])

Here I needed to introduce the second type parameter O, in order to align the proper output types. This compiles but at the use site it requires to specify both type parameters. Is there a way to specify only the A parameter (the case class) on the use site?

Paul Snively
@paul-snively
@kovszilard: What happens if you use Generic[A] instead of Generic.Aux?
Szilard Kovacs
@kovszilard
@paul-snively then the EnvReader output type won’t line up. Anyway I think I have to approach this problem from a completely differnet angle...
Paul Snively
@paul-snively
Probably.
JoelWAnna
@JoelWAnna

I'm trying to perform an operation on two coproduct values, is Poly2 an appropriate type for this?

something like this is fine

object multiply extends Poly2 {
implicit val intIntCase: Case.Aux[Int, Int, Int] =
at((a, b) => a * b)
implicit val intStrCase: Case.Aux[Int, String, Int] =
at((a, b) => b.length * a)
}

multiply(3, "4")

but I'd like to be able to use it on coproducts

type A = Int :+: String :+: CNil
multiply(Coproduct[A](3) , Coproduct[A]("4"))

but this doesn't compile

could not find implicit value for parameter cse: shapeless.poly.Case[Playground.this.multiply.type,Playground.this.A :: Playground.this.A :: shapeless.HNil]
Paul Snively
@paul-snively
@JoelWAnna: Just spitballing, but it seems like you need the cases in your Poly2 to themselves be Polys.
@JoelWAnna: I don't recall ever having tries to nest Polys like that, but I'm sure it's doable.
Ethan
@esuntag
I think your poly needs a Coproduct case and a Generic case
Or an A case that selects the appropriate case
JoelWAnna
@JoelWAnna

hmm, i've tried to come up with nested Polys , but it seems like it will be more difficult to read than a plain match,

maybe I'm going down the wrong path, maybe I should be converting them to an hlist and reducing them?

Szilard Kovacs
@kovszilard
Is it possible to read default values of case class fields using shapeless? If not could you point me to a good library or doc to achive this? (I guess it is only possible using macros)
Georgi Krastev
@joroKr21
@JoelWAnna maybe a bit late reply but have you taken a look at pureconfig?
Nikita Pedorich
@pedorich-n

Hi! I'm new to Shapeless and I have several questions and this piece of code, it's not really complex.
I'd be grateful if anyone would check it: https://scastie.scala-lang.org/pedorich-n/9ieO4UUDQ3yjQHNQG9KYfA/3.

So I have here an ADT named FileType, and holder FileEntry[T <: FileType] and some set of operations for these FileEntries.
I wonder if it's possible to make it more generic and let the compiler do all the job of matching Operations to FileTypes? Is it possible to derive FileEntryAny from AnyType, like Generic[FileEntry[AnyType]], so when I add new FileType I don't have to add it to FileEntryAny?

I feel like it's all possible, by using some Selector, Inject, Witness instances, but I can't really wrap my head about how to design this.
Thanks!

James Phillips
@jdrphillips
How do you find out which implicits are taking longest to resolve?
I've turned on the statistics flag and see that 97% of the time is spent in Typer, and 95% of that is spent on implicits
But things like "Successful in scope: 45%" are meaningless to me
I tried asking in scala but no one bit, I thought shapeless users probably have experience in this area
(macro expansion is not an issue for my particular project)
Teodor Dimov
@teodimoff
"Successful in scope: 45%" should mean that of all the implicits 45% are "applicable" ie they are "considered" .... i think. Olso they are reduced "early" by "shape of the type" in 2.13 i think.