Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Rob Norris
@tpolecat
Probably the easiest way is to add alleycats-core and import alleycats.std.map._ and then you can say .sequence
It's not strictly lawful because map traversal isn't congruent with equality and you can observe this with the Traverse instance. But it usually doesn't matter.
Abhishek Srivastava
@abhishes_twitter
great @tpolecat let me try this out. didn't know about alleycats :)
Minh Thai
@mt40
hi, anyone know where can I buy a physical copy of the book Scala with Cats?
Rob Norris
@tpolecat
@noelwelsh and/or @davegurnell ^^
Adam Rosien
@arosien
@mt40 we occasionally print copies of the books, but we don't currently have a way to publish on demand. sorry!
the book is free, so if you really wanted to, you could get it printed
Ryan Zeigler
@rzeigler
So, lets say I have a tagless encoding and I would like to add a localized state effect. The easy way is just to stack a StateT on top of my F, but if I wanted to use something like meow-mtl, does anyone know might I go about doing it? The only thing I can think of introducing some additional typeclass that knows how to convert F ~> G to add the state effect with a function receives a by name G[A] and an initial S returning an F[A]. This seems straightforward, but there doesn't seem to be a great way of introducing multiple local effects and seems generally kind of awkward. Does anyone have any pointers on a way of doing it?
Fabio Labella
@SystemFw
A couple of thoughts:
  • there are cases in which lack of higher-rank types and implicit function types really hurts, and you are forced to stick with concrete types
  • I don't see how F ~> G comes into place in this specific scenario
@rzeigler
My gut feeling is that you're in case no 1 and need both higher ranks and implicit function types, in which case I'd recommend just using the transformer locally instead (so StateT in this case). Anyway a small example would help
Ryan Zeigler
@rzeigler
So, I don't actually need the performance, I was just trying to figure out how to do it
The F, and G came into play, because there could be generally F and G = StateT[F, S, ?] which gives me G: MonadState, alternatively, the meow-mtl ref constructs all F = IO and G = IO and there's just an implicit MonadState floating around that works for "G"
Ryan Zeigler
@rzeigler
maybe the solution is just have a specific wrapper that knows how to bootstrap a state context for a set of operations and then delegates to some abstract implementation that requires the effect types. Then, the bootstrapper can be specialized for the base F type and the logical piece remains generic.
Jakub Kozłowski
@kubukoz
if you're using meow-mtl, you don't need a G
I mean... you can have a MonadState for your F that is IO
created from a Ref[IO]
alternatively you can have MonadState for F and F = StateT[IO
Ryan Zeigler
@rzeigler
yes, what I was trying to figure out how to do was introduce MonadState for any F locally while using meow-mtl when F = IO but keeping the encapsulating code unaware over the distinction
so, in that scenario, F might be G if you are using IO, but otherwise it won't
Jakub Kozłowski
@kubukoz
ok, I see what you're trying to do
btw. does this work?
      def localState[A](initial: S)(runState: MonadState[IO, S] => IO[A]): IO[A] =
        Ref[IO].of(initial).flatMap(_.runState(runState))
ah runState is from meow
right
Fabio Labella
@SystemFw

so, I don't actually need the performance, I was just trying to figure out how to do it

I'm not talking about perf at all, just expressiveness

Nick Telford
@nicktelford
Hi everyone, does anyone have any tips on how to debug diverging implicit expansions? The default compiler output isn't particularly helpful.
Fabio Labella
@SystemFw
I can tell you what the error is in 99% of the cases (unless you're using shapeless)
there's some method that needs an explicit type ascription like foo[F] somewhere
you can find it by finding a method that has a type parameter that then appears only in an implicit parameter list
for example def write[F[_]](a: String)(implicit F: Thing[F])
Nick Telford
@nicktelford
ahh, so it's usually caused by a type inference issue rather than a recursive implicit search?
@SystemFw what if that method itself is implicit :D
Rob Norris
@tpolecat
What is the exact message you're getting? It should tell you what the compiler is looking for. If it's not what you're expecting then you can often fix it with an explicit type argument at the point of failure.
If it is looking for what you're expecting then you may not have an instance in scope, but there may be something the compiler thinks will lead to an instance and it's off on a goose chase that will never end.
Fabio Labella
@SystemFw
@nicktelford depends on the context. If you're using shapeless (or code in shapeless style like inductive instances), then it's recursive search yeah (hence my initial caveat). In "normal" cats user code is the case I mentioned and that Rob has explained more often than not
Nick Telford
@nicktelford

so I have the following:

implicit def derived[A[_[_]], F[_], G[_]](implicit af: A[F],
                                          f: F ~> G,
                                          fk: FunctorK[A]): A[G] = fk.mapK(af)(f)

TopicsAlgebra[IO]

(I also have a bunch of impliclty calls to verify that the required implicits are in scope)

the error I'm getting is:

[error]      diverging implicit expansion for type TopicsAlgebra[cats.effect.IO]
[error]      starting with method derived
[error]      L87:          TopicsAlgebra[IO]

so as you can see, I can't add type ascriptions to the method call-site, because it's an implicit method

Rob Norris
@tpolecat
General observation, ~> isn't a typeclass so you don't normally want them to be implicit.
Also, how implicit is it? implicit af
sorry
Can you call derived explicitly with explicit type arguments and get the result you expect? It's possible those type parameters can't be inferred.
Nick Telford
@nicktelford
That works:
derived[ConnectionIO, IO](implicitly[TopicsAlgebra[ConnectionIO]], fk, TopicsAlgebra.functorK)
Fabio Labella
@SystemFw
a ConnectionIO ~> IO used like that seems scary :)
Nick Telford
@nicktelford
@SystemFw @tpolecat perhaps I'm asking the wrong question :) what's the idiomatic way to work with doobie within an http4s program?
Fabio Labella
@SystemFw
you shouldn't need any of that
Nick Telford
@nicktelford
I have my DAO algebras in ConnectionIO, and my HttpRoutes in IO - I've been trying to avoid passing the Transactor through to my http layer, in an effort to keep the http layer independent of ConnectionIO
Fabio Labella
@SystemFw
I would probably need more context about your code to give you a more precise answer, but generally I'd be explicit about when ConnectionIO becomes IO, given that that's where transaction boundaries are inserted
Nick Telford
@nicktelford
are there any non-trivial example repos you could point me to?
Rob Norris
@tpolecat
I think in general what I would do is have a service layer like trait Service[F[_]] { def getUser(id: int): F[User] } and then implement it, given a Transactor[F]. The implementation would be aware of doobie but outer layers wouldn't be.
Then it fits in with http4s's tagless design.