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
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
scalafmt
  • Loading branch information
kolov committed Aug 8, 2018
commit cf91908c2b9fff46400509883d75b171ef62fdfd
12 changes: 7 additions & 5 deletions src/main/scala/scalaz/reactive/Event.scala
Original file line number Diff line number Diff line change
@@ -1,19 1,21 @@
package scalaz.reactive
import scalaz.Monoid
import scalaz.zio.{IO, RTS}
import scalaz.zio.{ IO, RTS }

case class Event[A](value: Future[Reactive[A]]) extends RTS { self =>
case class Event[A](value: Future[Reactive[A]]) extends RTS { self =>

def merge(v: Event[A]): Event[A] = { // if Event[ A]: covariant type A occurs in contravariant position
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


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.


val io: IO[Nothing, Future[Reactive[A]]] = winner.map(_ match {
case Left((t, r)) =>
Future((t, Reactive(r.head, r.tail)))
Future((t, Reactive(r.head, r.tail)))
case Right((t, r)) =>
Future((t, Reactive(r.head, r.tail)))
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.

Expand Down
12 changes: 5 additions & 7 deletions src/main/scala/scalaz/reactive/Future.scala
Original file line number Diff line number Diff line change
@@ -1,17 1,17 @@
package scalaz.reactive

import scalaz.Scalaz._
import scalaz.reactive.Time.{NegInf, PosInf}
import scalaz.reactive.Time.{ NegInf, PosInf }
import scalaz.zio.IO
import scalaz.{Applicative, Functor, Monad, Monoid}
import scalaz.{ Applicative, Functor, Monad, Monoid }

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 class Future[ A](force: IO[Nothing, (Time, A)]) {

def [AA >: A](other: Future[AA]): Future[AA] =
def [AA >: A](other: Future[AA]): Future[AA] =
Future(force.flatMap {
case (t1, a1) =>
other.force.map {
Expand All @@ -29,9 29,8 @@ case class Future[ A](force: IO[Nothing, (Time, A)]) {
.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

})

def flatMap[B](f: A => Future[B]): Future[B] = {
def flatMap[B](f: A => Future[B]): Future[B] =
Future(force.flatMap { case (_, a) => f(a).force }) // FIXME - what to do with the times
}
}

object Future extends FutureInstances0 {
Expand Down Expand Up @@ -85,8 84,7 @@ trait FutureInstances2 {
override def point[A](a: => A): Future[A] =
Future.point(a)

override def bind[A, B](fa: Future[A])(f: A => Future[B]): Future[B] = {
override def bind[A, B](fa: Future[A])(f: A => Future[B]): Future[B] =
Future(fa.force.flatMap { case (_, a) => f(a).force })
}
}
}