Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
SemanticBeeng
@SemanticBeeng
so, no use of Nested, then?
Fabio Labella
@SystemFw
EitherT is similar to Nested
the difference is that Nested works for any F and G, but it can't have flatMap (it's an Applicative but not a Monad)
if you want a Monad you lose the ability to have one type for any F and G
and you need to use a transformer , where one of the types is known (in this case Either) and the other can vary
so you need EitherT in this case since you need flatMap to get to the List of IDs
SemanticBeeng
@SemanticBeeng
Yes, I felt the need for flatMap but liked Nested. Oki.
Fabio Labella
@SystemFw

I felt the need for flatMap but liked Nested

heh, this is the story of 10 years of FP research :joy:

but unfortunately you have encountered a fundamental limitations of effects
SemanticBeeng
@SemanticBeeng
Worked. Intellij cannot parse EitherT(dlRegistry.listDatasets(c.id)).map(_.map(_._2)) but, I will. ;-)
Fabio Labella
@SystemFw
cool, there are a few tricks you can use to learn how to work with types this way
you can get to a solution (in this case) by barely thinking about what the code should do, and only about types and shapes
SemanticBeeng
@SemanticBeeng
So, curious. Is there another way to stitch the same result together from pieces like I was trying? This is elegant but feel the need to cauterize that way of thinking about would help to see what it would take.
Fabio Labella
@SystemFw
wdym by another way? another method or another result?
I think that's how you would do it
you can write functions that basically do what traverse does
e.g. fold with mapN
SemanticBeeng
@SemanticBeeng
"only about types and shapes" - yes, I know. This is why I asked. Other than at this level one cannot really get it.
Fabio Labella
@SystemFw
well, I can give you a few hints
also, Haskell is nicer to learn this specific thing, but it works well in Scala as well
SemanticBeeng
@SemanticBeeng
Same result but somehow obtain the desired Task from the pieces my code creates. Those Task.Map or Task.Suspend
Fabio Labella
@SystemFw

Those Task.Map or Task.Suspend

No, those are bugs

those classes are internals of Task
SemanticBeeng
@SemanticBeeng
Ah. Was right to ask.
Fabio Labella
@SystemFw
it's like saying that you want to work with types of Some and None
you want to work with Option
same thing
(there are select cases in which you want to work with Some and None as types, but that's off topic)
another thing
if you have Task[_] as a return type
98% of the time you're papering over some error somewhere else
now, things that help
first of all, "find the F[_]"
SemanticBeeng
@SemanticBeeng
Yes, I know. That was a hack to confirm at least the root type. Did not mean it
Fabio Labella
@SystemFw
in your code F[_] = Task[Either[DataLakeRepositoryError, ?]]
this already helps you, because for example in another examples your Either could have different error types, so you know that you need some transformations to get to the same F
SemanticBeeng
@SemanticBeeng
yes
Fabio Labella
@SystemFw
once you know what your F is, you can decompose the problem:
  • how do I get from my type to a single F? (EitherT.apply)
  • how do I solve the problem in terms of F?
  • how do I get to my type from F? (_.value)
the ability to decompose problems is a selling point for FP. My experience training people tells me that it's uncommon to think that way, since with imperative programming decomposition is often not possible
now, for the second bullet point
you need to write down what you have, and what you want
when you start out, actually write those down
SemanticBeeng
@SemanticBeeng
Oki, thanks. Will mull on this and on the ... crack between Nested and EitherT. Examples somewhere?
Fabio Labella
@SystemFw

Haves:

  • F[List[Client]]]
  • Client => String (id)
  • String => F[List[(DataSpecification, DataSetRef)]]]

Wants:

  • F[List[DataSetRef]]
from there, I suggest to work backwards
i.e start from the result, and see what you need to get there
e.g the last step is from F[List[(DataSpec, DataSetRef]] to F[List[DataSetRef]]
that's map(_.map(_._2))
now, how do you get to F[List[(DataSpec, DataSetRef]]
and so on