Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
• Create your own community
Activity
Jakub Kozłowski
@kubukoz
EqualT?
I was thinking about sth like trait EqK[F[_]] { def eqv[A](x: F[A], y: F[A]): Boolean } before
Jakub Kozłowski
@kubukoz
you know what, this could actually work... an EqK[F[_]], Eq[A] => Eq[F[A]] derivation would be trivial
or EqK could just be a type alias: type EqK[F[_]] = Eq ~> λ[α => Eq[F[α]]]
with a derivation of Eq: implicit def eqKToEq[F[_] : EqK, A : Eq]: Eq[F[A]] = implicitly[EqK[F]].apply(Eq[A])
and instead of defining an Eq[List[A]] we'd define EqK[List], and the rest would be done by the conversion
massive incompatibilities though... without breaking the best we could do is probably define EqK as a separate typeclass, and duplicate the instances for Option, List etc. (I guess)
WDYT?
Jakub Kozłowski
@kubukoz
still confused why Eq[Cofree[List, Int]] breaks and Eq[Cofree[Option, Int]]doesn't
ah, I know. It would, I was just checking in CofreeSuite where it's defined explicitly :joy:
Jakub Kozłowski
@kubukoz
oh, and it looks like we'd need the same for Order and Show...
Mateusz Górski
@goral09
Hi, I am confused about use case for MVar and Ref. Looking at their interface they both provide methods for get: F[A] and set/put(a: A): F[Unit]. Can't MVar in place of Ref? I understand that MVar can be used as a communication channel ( blocking on get and put ) which is not possible with Ref.
Derek Williams
@derekjw
@goral09 A Ref wont block on get, but an MVar might if no value is available. So an MVar cannot be used in place of a Ref if a value is always expected.
Fabio Labella
@SystemFw
@goral09 a very, very important difference is that modify on Ref is atomic
just to give a bit of perspective, Ref and Deferred are coming from fs2, MVar is coming from Monix (and of course from Haskell, although in Haskell you also have STM)
when designing the new concurrency scheme in fs2, I made a decision to not go with MVar, separating the functionality into Ref and Deferred instead

Can't MVar in place of Ref?

Anyway if you do set/put, it will break in the presence of concurrency

so use Ref.modify
a Ref is also lighter weight
Fabio Labella
@SystemFw
(I guess I should specify, take/put on MVar for modification does work, but you end up having to worry about the state of the MVar, whether empty or full, and are at risk of deadlock)
Jakub Kozłowski
@kubukoz
what's MVar useful for, then? (in Scala)
if there are so many drawbacks
Fabio Labella
@SystemFw
well, I'm biased obviously since I consciously used to not go there. I think when dealing with synchronisation it might give slightly more control than Ref + Deferred, however at the price of significantly increased complexity as a design tool
for the record, in Haskell the recommended choice is STM unless you need fairness, which MVar gives you
Derek Williams
@derekjw
it's like a better SynchronousQueue
Jakub Kozłowski
@kubukoz
gotcha
@LukaJCB/@maintainers if you have a moment to look at my rant about Eq/diverging implicits (https://gitter.im/typelevel/cats?at=5b31861bce3b0f268d4311fa), please let me know if the idea to add a higher kinded Eq variant sounds appealing, I could come up with a proposal
Mateusz Górski
@goral09
Thanks @SystemFw and @derekjw
Ionuț G. Stan
@igstan
As far as I see, Ref + Deferred seems to be write-once, whereas MVar supports multiple writes (always alternated with reads, which makes it a single-element queue effectively).
Fabio Labella
@SystemFw
@igstan nope
Deferred is write-once
but with Ref + Deferred you can implement structures that aren't
e.g. Semaphore and Queue in fs2 are implemented with Ref + Deferred (used to be called Promise)
Mateusz Górski
@goral09
you could put new Deferred instances inside Ref right?
Fabio Labella
@SystemFw
that's exactly what you do
Mateusz Górski
@goral09
I will look at fs2's Queue implementation then
Fabio Labella
@SystemFw
the insight behind the design is this: separating synchronisation from concurrent state
trying to achieve orthogonality
MVar allows you to do both at once
whereas I started with Ref as something that could deal with concurrent state only
and that automatically drives some design decisions, e.g. it can't be empty (or you'd have to wait for reading, thus synchronisation)
Ionuț G. Stan
@igstan
@SystemFw I see, thanks.
Fabio Labella
@SystemFw
that also allowed a very very lightweight implementation in terms of a single AtomicReference (before the fs2 Ref was backed by a custom Actor implementation taken from scalaz)
after dealing with that, I tried to think about the simplest possible synchronisation semantics
and Deferred is very simple: starts empty, becomes full, can't be emptied or modified again. get on empty waits (asyncly), get on full immediately returns. complete on empty unblocks the readers, complete on full fails
even though they're simple, you can build many things with them
Mateusz Górski
@goral09
separating those two concerns makes sense. Although for building the communication channel, as in examples for MVar, it looks easier to get of the ground with MVar than Ref + Deferred
Ionuț G. Stan
@igstan
"Concurrent Programming in ML" has probably one of the best coverage of these concurrency concepts. Really underated book, IMO.
Fabio Labella
@SystemFw
@goral09 I disagree
MVar gives a lot more ways to end up in deadlock