Skip to content
This repository has been archived by the owner on Feb 14, 2021. It is now read-only.

Future=IO[Void,(Time,A) #15

Merged
merged 4 commits into from
Aug 15, 2018
Merged

Future=IO[Void,(Time,A) #15

merged 4 commits into from
Aug 15, 2018

Conversation

kolov
Copy link
Contributor

@kolov kolov commented Aug 8, 2018

Future =IO[Void, (Time, A)

@kolov kolov requested a review from VledicFranco August 8, 2018 17:15

def merge(
v: Event[A]
): Event[A] = { // if Event[ A]: covariant type A occurs in contravariant position
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not remove variance, the way it is done is by providing events of a supertype of A, so the type signature of merge must be:
def merge[AA >: A](v: Event[AA]): Event[AA]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks

): Event[A] = { // if Event[ A]: covariant type A occurs in contravariant position

val winner: IO[Nothing, Either[(Time, Reactive[A]), (Time, Reactive[A])]] =
self.value.force.map(Left(_)).race(v.value.force.map(Right(_)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to put them inside an Either, the resulting IO will have the winner, so self.value.force race v.value.force will be enough

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True - at one moment I had the idea I needed the loser too, but that is not the case.

Future((t, Reactive(r.head, r.tail)))
})

Event(unsafeRun(io)) // That is not good
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it is not good, we should NEVER use the RTS trait on our code, or we will be limiting our implementation to the jvm and it is clear that we are leaking side effects. this is why I said we can experiment with type Future[ A] = IO[Void, (Time, A)] so that in this case it is a simple race operation:

def merge[AA >: A](v: Event[AA]): Event[AA] = Event(self.value race v.value)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, once we are in IO, we have to stay in the IO, so I can't think of another way to do this at the moment.

implicit def monoidEvent[E, A]: Monoid[Event[A]] =
new Monoid[Event[A]] {

override def zero: Event[A] = Event(Future.Never)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we make Future = IO, then this is a good one because we would need to make an IO which never resolves and always loses race operations, maybe, for now, an IO with a fiber that is always blocked? we can analyze efficiency later

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i might be completely off here, but merge seems to be just a monoidal append in the paper, so should merge = where is the Future's ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@FrancoAra IO provides IO.never - Returns a action that will never produce anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hienqnguyen I guess we should do the racing in the Future's and end up with what you say.

import scalaz.{ Applicative, Functor, Monad, Monoid }

case class Future[ A](time: () => Time, force: () => A) {
object Types {
type Infallible[A] = IO[Nothing, A]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be type Infallible[ A] = IO[Void, A]? to ensure that this does not get flat mapped with an IO which does fail? or maybe I'm wrong

case (t1, a1) =>
other.force.map {
case (t2, a2) => if (t1 <= t2) (t1, a1) else (t2, a2)
} //There should be IO.ap, is there?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this has the same dilemma as the events... if we make Future[A] = IO[Void, (Time, A)] then I would say we shouldn't implement this monoid for now

Future(force.flatMap {
case (t, a) =>
f.force
.map { case (t2, f) => (t2.max(t), f(a)) } // There should be IO.ap, is there?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we could use IO ap instead of flatMap, I am not sure what are the difference in the semantics of the IO ap and flatMap, they are the same if ap is defined in terms of flatMap

@kolov kolov changed the title Future(IO[Noting,(Time,A)] Future=IO[Void,(Time,A) Aug 14, 2018
@kolov kolov merged commit 0bea549 into master Aug 15, 2018
@kolov kolov deleted the event-monoid branch August 15, 2018 18:08
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants