Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 09:45
    Travis milessabin/shapeless (master) passed (2662)
  • 09:20

    milessabin on master

    Update sbt-release to 1.0.12 Merge pull request #933 from sc… (compare)

  • 09:20
    milessabin closed #933
  • 09:20
    milessabin commented #933
  • Oct 16 18:47
  • Oct 16 18:22
    scala-steward opened #933
  • Oct 15 09:00
    Travis milessabin/shapeless (master) passed (2660)
  • Oct 15 08:34

    milessabin on master

    Update sbt to 1.3.3 Merge pull request #932 from sc… (compare)

  • Oct 15 08:34
    milessabin closed #932
  • Oct 15 08:34
    milessabin commented #932
  • Oct 14 19:40
  • Oct 14 19:14
    scala-steward opened #932
  • Oct 14 10:17
    Travis milessabin/shapeless (shapeless-3-staging) passed (2658)
  • Oct 14 10:15
    Travis milessabin/shapeless (shapeless-3) passed (2657)
  • Oct 14 10:14

    milessabin on shapeless-3-staging

    Use given imports Bumped Dotty and SBT versions. (compare)

  • Oct 14 10:13

    milessabin on shapeless-3

    Use given imports Bumped Dotty and SBT versions. (compare)

  • Sep 29 13:26
    Travis milessabin/shapeless (shapeless-3-staging) passed (2656)
  • Sep 29 13:26
    Travis milessabin/shapeless (shapeless-3) passed (2655)
  • Sep 29 13:24

    milessabin on shapeless-3-staging

    Use Symbol.tree directly Update companionModule API Remove redundant asClassDef and 1 more (compare)

  • Sep 29 13:23

    milessabin on shapeless-3

    Use Symbol.tree directly Update companionModule API Remove redundant asClassDef and 1 more (compare)

Zsolt Szilagyi
@esgott
Where type DecodeResult[T] = Either[String, T]. Then created instances for String and Int.
Then I created a type class, to extract values from the Map.
trait ArgumentDecoder[T] {
  def decode(args: Map[String, String]): DecodeResult[T]
}
And created instances for HList, and a generic one.
implicit val hnilDecoder: ArgumentDecoder[HNil] = new ArgumentDecoder[HNil] {
  override def decode(args: Map[String, String]): DecodeResult[HNil] = Right(HNil)
}

implicit def hlistDecoder[Key <: Symbol, Head, Tail <: HList](
  implicit witness: Witness.Aux[Key],
  headDecoder: Lazy[ConfigDecoder[Head]],
  tailDecoder: ArgumentDecoder[Tail]
): ArgumentDecoder[Head :: Tail] =
  new ArgumentDecoder[Head :: Tail] {
    override def decode(args: Map[String, String]): DecodeResult[Head :: Tail] = {
      val configKey = witness.value.name
      for {
        headValue <- args.get(configKey).toRight(s"Config with key $configKey not found")
        head      <- headDecoder.value.decode(headValue)
        tail      <- tailDecoder.decode(args)
      } yield head :: tail
    }
  }

implicit def genericDecoder[T, H](
  implicit generic: LabelledGeneric.Aux[T, H],
  headDecoder: Lazy[ArgumentDecoder[H]]
): ArgumentDecoder[T] =
  new ArgumentDecoder[T] {
    override def decode(args: Map[String, String]): DecodeResult[T] =
      headDecoder.value.decode(args).map(generic.from)
  }
But then when I try to use it with an actual case class, it won't find an implicit ArgumentDecoder.
case class Test(a: String, b: Int)
val config = Map("a" -> "av", "b" -> "1")
val result = ArgumentDecoder[Test].decode(config)
Can you tell me what am I doing wrong? I am not experienced with shapeless, so if this is not the best way to achieve this, that is also a really helpful information.
Radium
@radium226
I'm not sur at all, but I think you should have H <: HList in your genericDecoder
Fabio Labella
@SystemFw
if you don't have nested stuff you can use this as inspiration https://gist.github.com/SystemFw/03d66d65e471c98f02ba27d7180465b1
Zsolt Szilagyi
@esgott
thanks a lot, based on the inspiration, I changed the hlist decoder to the following, and it works
implicit def hlistDecoder[Key <: Symbol, Head, Tail <: HList](
    implicit witness: Witness.Aux[Key],
    headDecoder: Lazy[ConfigDecoder[Head]],
    tailDecoder: ArgumentDecoder[Tail]
  ): ArgumentDecoder[FieldType[Key, Head] :: Tail] =
    new ArgumentDecoder[FieldType[Key, Head] :: Tail] {
      override def decode(args: Map[String, String]): DecodeResult[FieldType[Key, Head] :: Tail] = {
        val configKey = witness.value.name
        for {
          headValue <- args.get(configKey).toRight(s"Config with key $configKey not found")
          head      <- headDecoder.value.decode(headValue)
          tail      <- tailDecoder.decode(args)
        } yield field[Key](head) :: tail
      }
    }
Paul Snively
@paul-snively
Is it sensible to have a Typeable instance for a Typeable[A]?
Miles Sabin
@milessabin
Do you mean Typeable[Typeable[A]]?
Paul Snively
@paul-snively
Yes. Alternatively, I could try to understand why case expressions with vals defined as Typeable[A] don't compare as equals.
I have a pattern match on Typeable[A]s, in other words, and none of the cases are matching.
One alternative that occurred to me is to try case _: TypeCase[Typeable[A]], but that's where I run into the fact that there's no Typeable instance for Typeable, which I admit seems reasonable.
So perhaps I should focus on the subtleties around equality of Typeable[A]s.
Miles Sabin
@milessabin
Well ...
Typeables aren't case classes in general, aren't per-type singletons and don't override default equality, so I think this is pretty much a non-starter as things are.
I confess I don't think I ever considered someone wanting to do what you're doing :-)
Why do you need to pattern match on a Typeable?
Paul Snively
@paul-snively
Yes, I suspected it's an odd case. :-)
I have a representation of a "schema" that's read at runtime.
So I parse type declarations, e.g. "long", to Typeable[Long]. This allows me to test conformance to the "schema" when I wish to construct values by looking up the Typeable for the field by name, in a Map. Of course, the value type of the map is then existential.
Now, in my test, I'd like to construct a value conforming to the "schema." I'd hoped that I could just map over the K, V pairs in the "schema," then use a case expression to map from the Typeable[A] to the appropriate ScalaCheck Gen for the type, e.g. case Typeable[Long] => Gen.choose(Long.MinValue, Long.MaxValue).
That doesn't work. It seems sensible for it not to work, for the reason you describe. But now I wonder what a reasonable alternative is.
Paul Snively
@paul-snively
This is the first hurdle I've encountered with the approach. The business of mapping my "schema" Map over the keys of my "value" Map to get the Typeable and call cast from it on the value from the "value" Map, resulting in Options for each of the prospective values, works like a charm.
Paul Snively
@paul-snively
  def genESO(schema: Schema[T forSome { type T >: Types }]): Gen[ESO[T forSome { type T >: Types }]] =
    Gen.nonEmptyMap {
      for {
        name  <- Gen.oneOf(schema.keys.toList)
        typ    = schema(name).typ
        value <- typ match {
          case `Typeable[String]`       => genNonEmptyAlpha
          case `Typeable[Long]`         => Gen.choose(scala.Long.MinValue, scala.Long.MaxValue)
          case `Typeable[Double]`       => Gen.choose(scala.Double.MinValue, scala.Double.MaxValue)
          case `Typeable[List[String]]` => Gen.containerOf[List, String](genNonEmptyAlpha)
          case `Typeable[List[Long]]`   => Gen.containerOf[List, Long](Gen.choose(scala.Long.MinValue, scala.Long.MaxValue))
          case `Typeable[List[Double]]` => Gen.containerOf[List, Double](Gen.choose(scala.Double.MinValue, scala.Double.MaxValue))
        }
      } yield (name, value.asInstanceOf[Types])
    }
For concreteness, that's the code that doesn't work, at least due to the match failure, and possibly for other reasons, too. :-)
Paul Snively
@paul-snively
There may be some variance oddities at play. For example, Metals tells me the type of schema(name).typ is Typeable[T]. But it also tells me the type of the typ on the left of the <- is Typeable[_ >: Types]. But then typ in typ match is again Typeable[T].
Miles Sabin
@milessabin
I would wrap the Typeable in something you can pattern match on.
Paul Snively
@paul-snively
Yeah. Hmm.
Katrix
@Katrix

So I've been playing around with type constructors lately. I got this type function on dotty to add and remove them

type AddRemove[W[_], Find[_[_], _[_], _], Replace[_[_], _[_], _], In] = In match {
  case Find[W, e, a] => Replace[W, e, a] 
}

I'm able to create type functions for add, remove outer, and remove inner seperately, but not as a shared thing as in the Dotty function.
This is what I have so far. I also tried to use =:= on the in type, and get the E and A types that way, but that doesn't work either.

Miles Sabin
@milessabin
This is a match type question, right? I think you'll have more luck in the dotty channel.
FWIW, that definition looks fine to me ... presumably it doesn't reduce at some use site or other?
Also, note that =:= can't be used in match types.
Katrix
@Katrix
Oh right, sorry, never posted what I have currently.
Stupid me
Miles Sabin
@milessabin
Hmm ... I don't have much time to stare at that right now. It'd help if you could reduce it to an absolute minimum ... just a single simple example that you think should compile but doesn't.
Katrix
@Katrix
I'll try thanks. Think it has something to do with including "function lambdas" in getting the types needed to progress
Katrix
@Katrix
Think this should be minimized enough. I included two encodings of the same thing. One compiles and the other one doesn't. For my bigger case neither encoding seem to compile, but here one of them does. https://gist.github.com/Katrix/81f27774cf49de86b40391610b0a0902
Ioan Gabriel Georgiu
@manufacturist

Hey guys. I'm trying to work with Selector and tagged types but ran into a simplification issue. I have the following working example: https://gist.github.com/manufacturist/33d956705957ea3ad6f103d6deaaad72

What I wanted to do was to simplify the approach and not use BasisConstraint at all; trying to avoid the need to add other string tagged types to the AllowedTaggedStringTypes hlist. One attempt (does not compile) was to refactor lines 37-48 into:

implicit def mkIdentifiable[T, HL <: HList](
  implicit
  gen: LabelledGeneric.Aux[T, HL],
  selectorId: Selector.Aux[HL, Witness.`'id`.T, @@[String, _]]
): Identifiable[T] = {
  new Identifiable[T] {
    override def id(t: T): String = selectorId(gen.to(t)).asInstanceOf[String]
  }
}

Is there any way to achieve this?

tayvs
@tayvs
hi guys. Can anybody help to understand how genTraitObjectEnum works. I need to generate schema and other typeclasses for sealed trait of objects and can not understand what I should enter as 3rd type parameter. The genTraitObjetcEnum looks next
  // This ToSchema is used for sealed traits of objects
  implicit def genTraitObjectEnum[T, C <: Coproduct, L <: HList](implicit ct: ClassTag[T],
                                                                 tag: TypeTag[T],
                                                                 gen: Generic.Aux[T, C],
                                                                 objs: Reify.Aux[C, L],
                                                                 toList: ToList[L, T]): ToSchema[T] = new ToSchema[T] {
    protected val schema: Schema = {
      val tpe = weakTypeTag[T]
      val namespace = tpe.tpe.typeSymbol.annotations.map(_.toString)
        .find(_.startsWith("com.sksamuel.avro4s.AvroNamespace"))
        .map(_.stripPrefix("com.sksamuel.avro4s.AvroNamespace(\"").stripSuffix("\")"))
        .getOrElse(ct.runtimeClass.getPackage.getName)
      val name = ct.runtimeClass.getSimpleName
      val symbols = toList(objs()).map(_.toString).asJava
      Schema.createEnum(name, null, namespace, symbols)
    }
  }
Darren Bishop
@DarrenBishop
Hello me again. Solve my other problem and understand ~90%~ of it. However today the compiler randomly started hanging with CPU spiking at 194% (htop)
An anyone suggest what/how to investigate at SBT just goes dark? Totally mythed and was about to start prep’ing a demo for Thursday
Darren Bishop
@DarrenBishop
Problem solved; switched on logging with -Xlog-implicits and went through the suspect case class, recursively, one by one and found the culprit - not ideal for the compiler to spin indefinitely though.
Paul Snively
@paul-snively
Unfortunately, Scala’s type system is Turing-complete. Even short of that, scalac is poorly engineered for performance in compiling heavily inductive implicit driven code like Shapeless. This is addressed by the inclusion of a heuristic for implicit resolution in Scala 2.13, if you can use that.
Katrix
@Katrix
How can I make this compile without having to specify the type parameter. Not quite sure if it's possible, or if I need some extra stuff to make it compile.
  trait Q[M[_[_]]] {
    def map[M2[_[_]]](f: M[Option] => M2[Option]): Q[M2]
  }

  val q: Q[λ[F[_] => F[String]]] = ???
  q.map[λ[F[_] => F[String]]](s => s)