Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functionality to construct products in applicative / monadic way #101

Merged
merged 10 commits into from
Sep 16, 2022

Conversation

joroKr21
Copy link
Member

@joroKr21 joroKr21 commented Sep 15, 2022

  • TODO: Add tests

@joroKr21 joroKr21 force-pushed the construct-ma branch 3 times, most recently from 96568d2 to c51430c Compare September 15, 2022 10:16
@joroKr21 joroKr21 self-assigned this Sep 15, 2022
@joroKr21 joroKr21 added the enhancement New feature or request label Sep 15, 2022
@joroKr21 joroKr21 marked this pull request as ready for review September 15, 2022 15:49
value <- fieldMap.get(field).toRight(s"Missing field '$field';")
parsed <- parser.parse(value, accum)
yield parsed
if accum then inst.constructA(parseField)(pure, map, ap)
Copy link
Member

Choose a reason for hiding this comment

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

I got so confused as to why constructA and constructM would be different for Either and then realized you're doing naughty things with ap 😂

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I didn't want to spend too much time defining Validated so I just used an inconsistent Either

final def erasedConstructA[F[_]](f: Any => F[Any])(pure: Pure[F], map: MapF[F], ap: Ap[F]): F[Any] =
traverseProduct(new ArrayProduct(is), (tc, _) => f(tc))(pure, map, ap)

final def erasedConstructM[F[_]](f: Any => F[Any])(pure: Pure[F], map: MapF[F], tailRecM: TailRecM[F]): F[Any] =
Copy link
Member

Choose a reason for hiding this comment

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

Is this just a stacksafe version of constructA or is there some other difference that I've missed?

Copy link
Member Author

Choose a reason for hiding this comment

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

constructA is based on Applicative:

  • It can be parallel
  • It cannot short circuit (evaluates for all fields)
  • It is not stack safe (currently) - but it could be optimized if we build a tree instead of a list of ap

constructM is based on Monad:

  • It is always sequential
  • It can short circuit
  • It is stack safe

Copy link
Member Author

Choose a reason for hiding this comment

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

cats.Applicative actually has map2Eval which can short circuit but that's too much complexity for Shapeless

Copy link
Member Author

Choose a reason for hiding this comment

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

@TimWSpence here is a failed attempt to make traverse and constructA stack safe: #103
But it doesn't actually build a tree ...

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, just saw this. Will have a look!

@joroKr21 joroKr21 merged commit 8b1bbc6 into typelevel:main Sep 16, 2022
@joroKr21 joroKr21 deleted the construct-ma branch September 16, 2022 10:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants