Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Soren
@srnb_gitlab
@matfournier That looks like MonoidK for Kleisli[Option?
It would be <+>
Sorry for the late response
Oh, SemigroupK
And you already had this discussion up ago and that wasn't a question
Now I look like a fool
Travis Brown
@travisbrown
If you use e.g. Traverse.ops or Traverse.nonInheritedOps, please speak up here: typelevel/cats#3330
matfournier
@matfournier
@srnb_gitlab Hah no worries. Yes, but <+> will run both branches for Kleisli[Option], which is behavior I did not expect. We got to the bottom of it.
Ryan Peters
@sloshy
Seems it also happens w/ Either (makes sense, and would expect it to happen for most other types like this)
Soren
@srnb_gitlab
I would expect orElse to be lazy
Is this grounds for a PR? I.e. should <+> for Kleisli be made lazy?
Rob Norris
@tpolecat
Where does it stop? I mean, in principle everything could be lazy.
Adam Rosien
@arosien
i've never liked the equating of Alternative and MonoidK because of this issue. i think it comes from stealing it from haskell where everything is lazy
maybe some technique like Parallel where you can switch modes between eager and lazy?
Christopher Davenport
@ChristopherDavenport
It's easily solved with Defer constraint, imo.
Which you can just satisfy with Eval to assert the behavior desired.
Eval makes a lot of the lazy/strict arguments uneccesarry.
Soren
@srnb_gitlab
Kleisli[OptionT[Eval?
Adam Rosien
@arosien
it's easily solved, if you know what to do, and why it is so. it may also be worthwhile to have a separate interface that does it for you, with separate docs, and warnings in the existing docs about the differences.
i guess i'll try to see what it would take, not trying to push tasks onto folks.
in any case there could be an improvement in docs about this semi-common case
Luka Jacobowitz
@LukaJCB
we could add a combineKEval or combineKDefer like how we have map2Eval to deal with laziness in an applicative context
matfournier
@matfournier
If I didn't go look at what http4s was doing, I don't think I would have discovered this in my own code until I was profiling and wondering why stuff was taking so long. I agree that Defer solves it, but you have to know. I see why it's happening when I go look at the semigroupK kleisli code. I don't think I would have figured out Defer to solve it on my own. It has been a good 24 hours of learning though!
Rob Norris
@tpolecat
Yeah reasoning about evaluation is hard.
Patrick Curran
@patrickthebold_twitter

Question about Validated the documentation says:

This one short circuits! Therefore, if we were to define a Monad (or FlatMap) instance for Validated we would have to override ap to get the behavior we want. But then the behavior of flatMap would be inconsistent with that of ap, not good.

Does anyone have more details on why that inconsistency is bad?

Context: I'm thinking about using cats-mtl with EitherT somewhere in my monad stack. But I'd like to combine my errors whenever things happen in parallel much like Validated provides.

I'm having a hard time reasoning about what's actually bad about making Validated a monad.

Christopher Davenport
@ChristopherDavenport
Monad laws says ap must be consistent with flatMap
Patrick Curran
@patrickthebold_twitter
Interesting. None of the laws here https://wiki.haskell.org/Monad_laws mention ap explicitly. Is there a derivation of that fact based on those three laws?
Christopher Davenport
@ChristopherDavenport
In haskell Monad implies Applicative, so it's that way by default.
Patrick Curran
@patrickthebold_twitter
Sure, all Monads are Applicative, but the laws don't mention ap. So I don't see how overriding ap would break any of the laws.
Christopher Davenport
@ChristopherDavenport
I know if I wrote code I expected to short-curcuit but didn't it would break my ability to reason about code. I also know that we codify our laws that way. I'm sure there's someone more mathematically oriented that can direct you to source material. My 2 cents is not being consistent would make it impossible to reason about the behavior.
Luka Jacobowitz
@LukaJCB
The laws do mention ap though, both in Haskell and cats
Patrick Curran
@patrickthebold_twitter
@ChristopherDavenport I suppose that's fair, @LukaJCB Do you have a link? The three monad laws I linked don't seem to, at least not directly.
I think those monad laws might be written before applicative was a superclass of monad

m1 <*> m2 = m1 >>= (x1 -> m2 >>= (x2 -> return (x1 x2)))
Patrick Curran
@patrickthebold_twitter
Thanks I was having a hard time reading through that :-)
Luka Jacobowitz
@LukaJCB
Yeah it can be a lot
But it's basically saying that if you define ap using flatmap it should be the same thing
And I think it's a good law, because it follows the rule of least surprise
Patrick Curran
@patrickthebold_twitter
ok this might be a dumb question, but if I'm using IO and end up making, say network calls, and I use traverse over a list of calls to make, those all happen in parallel I would think, but then, somehow traverse unwinds into calls to ap which in turn is equivalent to some combination of flatMap, but the flatMap doesn't force sequential calls? ( I need to trace through how this all works :-))
ok I need to go to sleep, but thanks for the pointers.
Luka Jacobowitz
@LukaJCB
They don't happen in parallel with traverse
You get parallelism with parTraverse
Patrick Curran
@patrickthebold_twitter
Not yet, very much just getting started. I need to look at that. Thank you.
Luka Jacobowitz
@LukaJCB
Yeah, and feel free to ask any questions that pop up when you're reading :)
I think I wrote that 3 years ago, so I might be able to better answer questions nowadays with more experience
Patrick Curran
@patrickthebold_twitter
Did a quick glance, does that mean if I use parTraverse on EitherT[IO, NonEmptyList[A], B] I can get parallel execution and accumulation of errors?
(I think I got hit by the x y problem) because that's really what i want.