Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Sep 05 2019 14:43
    @typelevel-bot banned @jdegoes
  • Jan 31 2019 21:17
    codecov-io commented #484
  • Jan 31 2019 21:08
    scala-steward opened #484
  • Jan 31 2019 18:19
    andywhite37 commented #189
  • Jan 31 2019 02:41
    kamilongus starred typelevel/cats-effect
  • Jan 30 2019 00:01
    codecov-io commented #483
  • Jan 29 2019 23:51
    deniszjukow opened #483
  • Jan 29 2019 23:37
  • Jan 29 2019 23:22
  • Jan 29 2019 20:26
    Rui-L starred typelevel/cats-effect
  • Jan 29 2019 18:01
    jdegoes commented #480
  • Jan 29 2019 17:04
    thomaav starred typelevel/cats-effect
  • Jan 28 2019 17:43
    asachdeva starred typelevel/cats-effect
  • Jan 28 2019 07:12
    alexandru commented #480
  • Jan 28 2019 05:45
    codecov-io commented #482
  • Jan 28 2019 05:35
    daron666 opened #482
  • Jan 27 2019 13:56
    codecov-io commented #481
  • Jan 27 2019 13:46
    lrodero opened #481
  • Jan 27 2019 05:47
    codecov-io commented #460
  • Jan 27 2019 05:37
    codecov-io commented #460
rnd4222
@rnd4222_gitlab
So I wanted to know if its usual approach or not
Adam Rosien
@arosien
hmm. so for the impls/interpreters of those algebras there isn't 1 type like IO that's used for F, there are multiple, so you end up translating a lot?
is there some intermediate type like class BizLogic[F[_]](alg1: Alg1[F], alg2[Kleisli[F, Dependency]])? because something like that would be difficult.
or at least more complicated than it probably should be. but i'm just guessing because i'm not sure of the structure you are describing.
rnd4222
@rnd4222_gitlab
It's usually in a places where some context is added/eliminated, for example in HttpRoutes or SomethingRepository
typical signature is
def withRequestId[F[_], G[_] : WithRun[*[_], F, RequestId[F]](routes: HttpRoutes[F]): HttpRoutes[G]
Adam Rosien
@arosien
i definitely know that there are good reasons to need to lift/unlift between types, especially with Kleisli. but where that happens is the question.
rnd4222
@rnd4222_gitlab
I'm thinking that using Kleisli in this example would be much better:
def withRequestId[F[_], G[_] : WithRun[*[_], F, RequestId[F]](routes: HttpRoutes[F]): HttpRoutes[G]

// vs

def withRequestId[F[_]](routes: HttpRoutes[F]): HttpRoutes[Kleisli[F, RequestId[F], *]
Adam Rosien
@arosien
yeah that signature makes sense, sort of.
i see now what you're saying about monad transformers vs. typeclass constraints.

the former is more flexible, although it is likely that only Kleisli has a WithRun instance i'm guessing.

it's a familiarity issue, like you said. i think more folks would understand the Kleisli version since it is more "concrete"

Adam Rosien
@arosien
but i can see how some business logic is going to depend on [F[_]: WithRun[...]](routes: HttpRoutes[F]) which makes the context bound version more congruent
so... i feel ya.
Georgi Krastev
@joroKr21
It depends. With ApplicativeAsk it was easy to migrate from Kleisli to Monix TaskLocal. But it's better to have higher level interfaces like Logger. When converting to routes it sounds like a place to use concrete types though.
Adam Rosien
@arosien

there's the evalMap(f: A => F[B]): Resource[F, A] => Resource[F, B] = _.flatMap(a => Resource.liftF(f(a))) combinator that lifts the output of f into an "inner" Resource.

what about a different combinator that uses the first Resource to create the next, where the first can be released: evalUse(f: A => F[B]): Resource[F, A] => Resource[F, B] = rfa => Resource.liftF(rfa.use(f))?

or is there a better way?
Fabio Labella
@SystemFw
that's it
Keir Lawson
@keirlawson
Is there a nice pre-existing fake impl of Clock for use with tests? Obviously I can make my own but figured there might be something already?
Fabio Labella
@SystemFw
TestContext
Gavin Bisesi
@Daenyth
@keirlawson example integration with scalatest here https://gist.github.com/Daenyth/67575575b5c1acc1d6ea100aae05b3a9
Adam Rosien
@arosien
very quiet today in the gitterverse.
Michael Pilquist
@mpilquist
@arosien_twitter you’ve gotta hang out in cats-effect-dev channel
Adam Rosien
@arosien
:O
Fabio Labella
@SystemFw
yeah I think this channel is going to be for user questions (which I think is a good thing)
Aleksander Sumowski
@aleksandersumowski
hi all,
what would be a good way to extend IO.race to more then 2 tasks?
Fabio Labella
@SystemFw
@aleksandersumowski do they all return the same thing?
things of the same type I mean
Aleksander Sumowski
@aleksandersumowski
yes
This message was deleted
Fabio Labella
@SystemFw
@aleksandersumowski this should work
def multiRace[F[_]: Concurrent, A](fas: List[F[A]]): F[A] = {
  def spawn[B](fa: F[B]): Resource[F, Unit] =
    Resource.make(fa.start)(_.cancel).void

  def finish(fa: F[A], d: Deferred[F, Either[Throwable, A]]): F[Unit] =
    fa.attempt.flatMap(d.complete)

  Deferred[F, Either[Throwable, A]]
    .flatMap { result =>
      fas
        .traverse(fa => spawn(finish(fa, result)))
        .use(_ => result.get.rethrow)
    }
}

def program(i: Int) = {
  for {
    wait <- IO(scala.util.Random.nextInt(1000))
    _ <- IO(println(s"program $i waiting for $wait millis"))
    _ <- IO.sleep(wait.millis)
    _ <- IO(println(s"program $i finished"))
  } yield i
}.guarantee(IO(println(s"program $i finalised")))

def test = multiRace(List.range(0, 5).map(program)).unsafeRunSync
Aleksander Sumowski
@aleksandersumowski
thanks a lot!
Daniel Ochoa Rodríguez
@tzimisce012
About this PR: typelevel/cats-effect#365 Does it miss ConcurrentEffectfor IorT or am I missing something?
Vasil Vasilev
@vasilmkd
surprise, it was traverse
Daniel Ochoa Rodríguez
@tzimisce012
?
Anton Sviridov
@keynmol
just a running gag about .traverse being the answer to pretty much any cats-effect question online :)
Paul Snively
@paul-snively
It's really interesting how often questions reduce to "How do I turn a Traverse of A into a B[Traverse] given an A => F[B]? And enough Fs form Applicatives that the answer really is traverse.
Anton Sviridov
@keynmol
I actually wonder if Future.sequence pops up with same frequency. May be it's because it's part of a smaller public Future interface that it's discovered more easily
Daniel Ochoa Rodríguez
@tzimisce012
oh, it was related with the previous question, I was out of context
Vasil Vasilev
@vasilmkd
ah, sorry for the confusion :)
Fabio Labella
@SystemFw
tbh, there is enough going on in that code that "just use traverse" doesn't feel fair :)
Vasil Vasilev
@vasilmkd
completely agree
Adam Rosien
@arosien
i was going to approach the multi-race as a fold using race, but i liked @SystemFw's solution
Gabriel Volpe
@gvolpe
Adam Rosien
@arosien
cool
i'm saving things like these for advanced exercises
Fabio Labella
@SystemFw
probably a good idea to add an attempt after complete, although it doesn't affect correctness
James Rockett
@jrockett6
Does IO always have to "bubble up" through your code?
Like, if I have a bunch of nested functions, and one deeply nested function wants to get command line input or something, that function needs to return an IO right? and now all calling functions must return some form of IO[F] or a monad transformer or something (when say previously they just returned an Option or something)
If that makes sense..
sinanspd
@sinanspd

and now all calling functions must return some form of IO[F]

Is F another effect here or were you just referring to some arbitrary wrapped type?