by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Alexandru Nedelcu
@alexandru

New PR: monix/monix#726

Oleg Pyzhcov
@oleg-py
So it's catnap now :D
Alexandru Nedelcu
@alexandru
catnip was taken :)
Oleg Pyzhcov
@oleg-py
It's so cold and rainy outside, I could use a catnap myself
Alexandru Nedelcu
@alexandru
Yes, laziness wins 😛
Oleg Pyzhcov
@oleg-py
But not by default :smirk:
Alexandru Nedelcu
@alexandru
@themirrortruth for your question, @gvolpe's answer is correct ... onErrorRestartLoop is basically just a loop built with onErrorHandleWith, named handleErrorWith in Cats (which is flatMap for errors)
Gabriel Volpe
@gvolpe
:+1: :smiley:
Igor Ramazanov
@igor-ramazanov
@alexandru @gvolpe Thank you!
SemanticBeeng
@SemanticBeeng
Trying to use cats.data.Nested with Task based apis and getting stuck
      type Dataset = (DataSpecification, DataSetRef)

      val clients = Nested[Task, Either[DataLakeRepositoryError, ?], Seq[Client]](dlRegistry.listClients())

      def clientDatasets(client: String) =
        Nested[Task, Either[DataLakeRepositoryError, ?], Seq[Dataset]](dlRegistry.listDatasets(client))

      val r: Task[_] = (clients map { cls: Seq[Client] ⇒
        cls map { client ⇒
            (clientDatasets( client.id) map { dsds: Seq[Dataset] ⇒
              dsds map { ds ⇒
                ds._2.shortName.pp("\n\n"); ds
              }
            }).value
          }

        }).value

     s"r is ${await(r)}".pp
Gives r is Right(List(Task.Map$995060245, Task.Map$958851644, Task.Map$119297310, Task.Map$713902690, Task.Map$1792185060, Task.Map$1688986248))
SemanticBeeng
@SemanticBeeng
Instead I'd like a single Task to runAsync for result.
Tried Task.sequence and other things but the result is always something else than desired.
For context about cats.data.Nested see https://typelevel.org/cats/datatypes/nested.html
You can glean from code above but apis are
def listClients(): Task[Either[DataLakeRepositoryError, Seq[Client]]] 
def listDatasets(clientId: String): Task[Either[DataLakeRepositoryError, Seq[(DataSpecification, DataSetRef)]]]
In some variants of this was getting instances of Task.Suspend and did not know what to do with them.
@oleg-py - thoughts please?
Alexandru Nedelcu
@alexandru
@SemanticBeeng what result do you expect?
Task.Suspend is internal, that's not what matters, but rather the type you're expecting.
SemanticBeeng
@SemanticBeeng
A Task that when runAsync-ed gives the entire/concatenated list of shortNames of traversed DatasetRefs for all the Clients
Fabio Labella
@SystemFw
I assume _.id: Client => String does the right thing
SemanticBeeng
@SemanticBeeng
yes. In fact. running the inner part for one Client gives such a result. (Task as per above)...
Fabio Labella
@SystemFw
btw you should have those things return List, and not Seq, or you won't be able to use many cats abstractions
SemanticBeeng
@SemanticBeeng
Ah.
Fabio Labella
@SystemFw
also, this would be easier with ListT (and therefore fs2.Stream, monix.Iterant, monix.Observable)
but the trick there is to imagine what you would do with F[List[Client]] and String => F[List(DataSpec, DataRef)]
so, first .flatMap to get to List[Client]
then traverse(c => listDataSets(c.id))
actually, flatTraverse
I'll write a snippet down
SemanticBeeng
@SemanticBeeng
thanks. parsing...
Fabio Labella
@SystemFw
yeah I'll just write the code
SemanticBeeng
@SemanticBeeng
This "rings" better than mine, the intuition being to not interrupt the flow with separate, disjoint, mapcalls. Right? Feels like Task create intermediate instances that need special action to run.
Fabio Labella
@SystemFw
yeah once you get there it means (in many but not all cases) that you've strayed off the right path
SemanticBeeng
@SemanticBeeng
oki. That is the reason I reached to Nested.
Fabio Labella
@SystemFw
that's a separate thing
you still need Nested/EitherT
(and ideally, if you could do it with Stream/Observable rather than List, it would be easier still)
but I'll write a solution with List
you actually need EitherT here, not just Nested , because you have some flatMaps
SemanticBeeng
@SemanticBeeng
Refactored apis to List.
Fabio Labella
@SystemFw
object Ex {
  import cats._, data._, implicits._
  import cats.effect._

  type Task[A] = IO[A]
  type DataLakeRepositoryError
  type DataSpecification
  type DataSetRef

  case class Client(id: String)

  def listClients: Task[Either[DataLakeRepositoryError, List[Client]]] = ???
  def listDatasets(clientId: String): Task[Either[DataLakeRepositoryError, List[(DataSpecification, DataSetRef)]]] = ???

  def result: Task[Either[DataLakeRepositoryError, List[DataSetRef]]] =
    EitherT(listClients).flatMap { clients =>
      clients.flatTraverse(c => EitherT(listDatasets(c.id)).map(_.map(_._2)))
    }.value
}
that .map(_.map(_._2)) is a bit ugly, but it is what it is
(sorry for using IO in this channel :P )
SemanticBeeng
@SemanticBeeng
oki, thanks. will try to use that.
Fabio Labella
@SystemFw
you can still use Task ofc, just to be clear