Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • May 13 17:51

    mergify[bot] on master

    Update scalafmt-core to 3.5.3 Merge pull request #346 from sc… (compare)

  • May 13 17:51
    mergify[bot] closed #346
  • May 13 17:30
    scala-steward opened #346
  • Apr 21 10:32

    mergify[bot] on master

    Update scalafmt-core to 3.5.2 Merge pull request #345 from sc… (compare)

  • Apr 21 10:32
    mergify[bot] closed #345
  • Apr 21 09:55
    scala-steward opened #345
  • Apr 17 02:52

    mergify[bot] on master

    Update discipline-core to 1.5.1 Merge pull request #344 from sc… (compare)

  • Apr 17 02:52
    mergify[bot] closed #344
  • Apr 17 02:41
    scala-steward opened #344
  • Apr 11 20:14

    mergify[bot] on master

    Update sbt-typelevel, ... to 0.… Merge pull request #343 from sc… (compare)

  • Apr 11 20:14
    mergify[bot] closed #343
  • Apr 11 19:51
    scala-steward opened #343
  • Apr 11 09:05

    mergify[bot] on master

    Update sbt-typelevel, ... to 0.… Merge pull request #342 from sc… (compare)

  • Apr 11 09:05
    mergify[bot] closed #342
  • Apr 11 08:55
    scala-steward opened #342
  • Apr 10 02:56

    mergify[bot] on master

    Update discipline-core to 1.5.0 Merge pull request #341 from sc… (compare)

  • Apr 10 02:56
    mergify[bot] closed #341
  • Apr 10 02:44
    scala-steward opened #341
  • Apr 08 07:51

    mergify[bot] on master

    Update scalacheck to 1.16.0 Merge pull request #340 from sc… (compare)

  • Apr 08 07:51
    mergify[bot] closed #340
Keir Lawson
@keirlawson
^ this is giving me Cannot expand @autoFunctorK with Scala 2.13.4, clearly something in my setup is messed up, anyone any ideas what it could be?
I'm using "org.typelevel" %% "cats-tagless-macros" % "0.12"
Keir Lawson
@keirlawson
ok so its me being a numpty :D
didn't have -Ymacro-annotations
though in my defence whilst the install instructions on the github mention this, those on the microsite do not
Georgi Krastev
@joroKr21
yep sorry about that and thanks for the PR :thumbsup:
Jonas Chapuis
@jchapuis
hey, how difficult would it be to add BiFunctorK and the corresponding derivation for algebras with two parameters?
Diego E. Alonso Blas
@diesalbla
@jchapuis What would be the key operation of that BiFunctorK ?
I suppose you could just try copying and adapting the code of FunctorK... would it be fairly symmetrical?
Bifunctor being something like F[_, _], and a BifunctorK being for algebra types of the form A[ _[_, _]] ,
you may still have function mapK[G[_, _]](fk: F ~> G) ...
Jonas Chapuis
@jchapuis
thanks, yeah so I thought, I might give it a shot. Indeed I would like to have it to "mapK" bifunctorial algebras
Jonas Chapuis
@jchapuis
well, not so easy. Simulacrum only support single-parameter type constructors, and cats FunctionK likewise is for unary parameter types, I can't express a natural transformation between bifunctors using it
Andrey Patseev
@patseev
Hey guys. How to solve the situation when I need both ApplyK and Aspect for my algebra? Can't auto-derive because both extend FunctorK and this leads to ambiguity.
I've kinda solved this by deriving Aspect and SemigroupalK instead and on "call-site" requiring FunctorK and SemigroupalK and re-implementing map2K manually there. But it's ugly and doesn't feel like a proper solution
Georgi Krastev
@joroKr21
Hmm good question - do you mean that you can't use them? I don't think deriving would be a problem.
Andrey Patseev
@patseev
Yeah, I meant that I can't use it due to ambiguity of FunctorK in the scope. Deriving works.
Georgi Krastev
@joroKr21
That's the same problem with Applicative and Traverse in cats
I guess a workaround would be to use mapK from the companion object or directly from the typeclass
It's not ideal
The former if you're using the macro annotations
Andrey Patseev
@patseev
Gotcha. Thank you!
Ben Spencer
@dangerousben
in this first faq, what would the type of the generated FunctorK instance look like (in kind-projector syntax)? https://typelevel.org/cats-tagless/faq.html#does-cats-tagless-support-algebras-with-extra-type-parameters
Ben Spencer
@dangerousben
FunctorK[Foo[*[_], T forSome { type T }]] ?
Ben Spencer
@dangerousben
or does it generate a different FunctorK for each value of T?
Georgi Krastev
@joroKr21
@dangerousben it would generate a method implicit def functorK[T]: FunctorK[Foo[*[_], T]] = ???
Ben Spencer
@dangerousben
right, thanks
ivan-klass
@ivan-klass
Guys, perhaps I'm missing something, but out of curiosity, why does autoSemigroupalK require all F[_] positions to be covariant? I think that given two algebras (say, algG: Alg[G], algH: Alg[H]) a product Alg[Tuple2K[G, H, *]] can handle input argument t2k: Tuple2K[G, H, A] with passing t2k.first to algG and t2k.second to algH correspondingly. Am I wrong with something here?
Georgi Krastev
@joroKr21
Hmm interesting, I never thought about it - do you want to give it a try?
Georgi Krastev
@joroKr21
I've released 0.14.0 with the SemigroupalK changes: https://github.com/typelevel/cats-tagless/releases/tag/v0.14.0
Brian P. Holt
@bpholt

We have a lot of generated code for working with Thrift services that has a tagless-style trait with implementations in Twitter Futures. When we pull those into a cats-effect app, we’re writing a lot of boilerplate implementations that delegate the actual work to the Future-based impl, wrapping each of those calls in Async[F].async and Sync[F].delay.

Does that sound like the kind of thing that Aspect / Codomain could help with?

Georgi Krastev
@joroKr21
@bpholt I think mapK is enough - you just need def async[F[_]: Async]: Future ~> F if I understand correclty
Oh no wait, I guess the problem with mapK is that it will call the service before mapping it, thus triggering the side effect
Georgi Krastev
@joroKr21
I guess your best bet is Derive.readerT[Service, Future].mapK[F](provide(service)) where
def provide[F[_], R](service: R)(implicit F: Async[F]): ReaderT[Future, R, *] ~> F =
  λ[ReaderT[Future, R, *] ~> F](r => F.fromFuture(F.delay(r(service))))
Georgi Krastev
@joroKr21
I even made it into a test: #250
Brian P. Holt
@bpholt
Oh wow, that’s great. Thanks!
Brian P. Holt
@bpholt
FYI, we turned that ReaderT provide idea into a little microlibrary that enables an asyncMapK[F]on an algebra. I’d love feedback, or even to merge it into cats-tagless itself, if that makes sense.
Mark de Jong
@Fristi
Cool
shapeless 3 has FunctorK deriving for case classes
Woop :)
But what's needed for traits? Guess it doesn't work
Georgi Krastev
@joroKr21
There are no mirrors generated for traits
But I think we can port cats-tagless to Scala 3 and also add case class support via shapeless - it just won't be easy because the traits are the main use case and there we have to write macros
Georgi Krastev
@joroKr21
@bpholt that's pretty cool :thumbsup: - looking at the support matrix perhaps it's better if it stays as a micro library. I think it would be reasonable to have a cats-effect module but I'm less sure about the twitter futures
Brian P. Holt
@bpholt
Yeah I agree, I would keep the Twitter stuff out of it
But maybe the AsyncFunctorK and stdlib instances could be added to a cats-tagless-effect or something, idk
Jonas Chapuis
@jchapuis

hey guys, would you know why

implicit def loggerAutoDerive[F[_], G[_]](
    implicit af: Logger[F],
    functorK: FunctorK[Logger],
    fk: F ~> G
  ): Logger[G] = functorK.mapK(af)(fk)

works, but the more generic higher-kinded version of this:

implicit def autoDerive[F[_], G[_], Alg[_[_]]](
    implicit af: Alg[F],
    functorK: FunctorK[Alg],
    fk: F ~> G
  ): Alg[G] = functorK.mapK(af)(fk)

is diverging and I can't get it to work? I suppose that's why cats-tagless has that as a macro but was curious why the compiler isn't capable to resolve it. Thanks!

Georgi Krastev
@joroKr21
Hey @jchapuis let me try to explain. Let's say you want to summon Alg[G] for some known Alg and G - for example Logger[IO]. The problems is that at this point the Scala compiler doesn't know what F is - it could be anything including IO itself. And if we assume it could be IO, then when we look for Alg[F] we are actually looking for Logger[IO] again which circles back to the same implicit autoDerive and we create a cycle. You could break this cycle if you reorder the implicit arguments like this:
implicit def autoDerive[F[_], G[_], Alg[_[_]]](
    implicit fk: F ~> G,
    af: Alg[F],
    functorK: FunctorK[Alg]
  ): Alg[G] = functorK.mapK(af)(fk)
This way F can be determined before we look for Alg[F]. But now you need to be really careful what kind of implicit F ~> G transformations you have in scope (for example if you had IO ~> IO we would end up with the same problem.
Georgi Krastev
@joroKr21
Now I would go on a tangent and recommend that you don't do this at all :smile: - these complex implicit resolution problems are one valid criticism of tagless final in Scala and I would recommend that you go for a simpler approach where you pass your tagless final interfaces as regular constructor parameters. In a way that higher-level implementations depend on lower-level interfaces as constructor parameters. The only difference is that they are not implicitly resolved - you just do mapK and co as needed when you pass arguments to your constructors.
Take for example class CustomerEmailService[F[_]](customerRepository: Repository[F], emailClient: Client[F]) extends EmailService[F] - now you can do new CustomerEmailService(customerRepository.mapK(transactional: ConnectionIO ~> IO, emailClient.mapK(retrying: IO ~> IO)) etc. - note how retrying doesn't change the type. That would be hairy to make it work with implicits because of ambiguity.
Dan Di Spaltro
@dispalt
@bpholt oh man that's great, I was just dealing with this with Id[A]
3 replies