Where communities thrive

  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
Repo info
  • 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
Gavin Bisesi
whatever you flatMap after that does whatever you tell it
Arnau Abella
I was thinking it the other way :O
Gavin Bisesi
I'm fairly certain an implementation that would make your example above handle boom would need to end up violating some applicative/functor laws somewhere along the way
I don't feel like writing that all out :P
but anyway - it doesn't work like that
Fabio Labella
you can actually see why the behaviour your seek is impossible as soon as you have things that don't return Unit
def ints: IO[Int] = 3.pure[IO].handleErrorWith(e => 4.pure[IO])
  // this is handleError
def string: IO[String] = (ints <* boom).map(_.toString) 
  // if handleErrorWith worked here you'd try to return an Int instead of a String
if handleErrorWith installed a handler which is valid for all IOs flatMapped after this, which type should it return?
it can only be IO[Nothing], which can only be something that never terminates (IO cannot emit zero values)
Arnau Abella
Makes sense, the signature also gives some hints avoit it
Fabio Labella
the behaviour which is closest to what you seek is the release action in Stream or Resource
Arnau Abella
I'll have a look at them tomorrow
Then, what is the purpose of handleErrorWith ?
Running a piece of code that is suspicious of throwing errors ?
Fabio Labella
handling the errors of the current IO
it's the equivalent of catch
e.g. imagine wanting to return different http responses on success or failure of an operation
or perhaps wanting to retry something when there's an error
like, I don't see why this model is confusing
you have
IO.unit.handleError(...) >> boom, which doesn't handle errors in boom
just like
try {
} catch {

doesn't handle errors in boom
Arnau Abella
It's not confusing now at all
Fabio Labella
ah, nice ;)
Arnau Abella
but I couldn't understand it the first time :S
so thanks
Fabio Labella
heh, that's ok
Arnau Abella
How do you handle situation where you fork then cancelled (e.g. the resource is not available) but there is a join afterwards ?
Fabio Labella
you are going to have to be a bit more specific
that use of the word "cancelled" doesn't necessarily map to what I would think in the context of a fork
i.e. it's unclear if you are talking about some logical notion of "I don't want to do this anymore", or actual fiber interruption
Arnau Abella
Fiber interruption (e.g. Fiber.cancel)
I mean I dont want to do that anymore as .cancel
Fabio Labella
who cancels? the thing that would do the join otherwise or something else?
Arnau Abella
The thread you forked from with .start
Fabio Labella
and who joins?
I think it would be better if you could sketch an actual example. This can be tricky so it's easier that way
Arnau Abella
  (for {
    fiber <- readFile(new File("data/lore.txt")).start
    _     <- IO.sleep(100.millis) *> fiber.cancel
    lore  <- fiber.join // blocks
  } yield lore).map { println(_) }.unsafeRunSync()
Fabio Labella
well, that's kinda contrived given that this specific control flow doesn't really make a lot of sense, you alwasy join after cancel has happened
there are three things I'd say
if you just want to put a timeout on something
you should just readFile.timeout(5.seconds) (assuming that your readfile implementation is cancelable)
number 2 would be to only call .join if you haven't called cancel. In the simplest case this is an if, in more complicated cases you might need some coordination between the interrupter and the joiner
number 3 would be to put the result in a Ref + Deferred thing (in this case a simple Deferred), which has some form of default, this simplest case of which would be Deferred[Option[Thing]]
then you need to bracketCase or guaranteeCase the started operation so that it puts None on that Deferred when it gets cancelled
Arnau Abella
All three points are clear
nothing to add