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 common Functor#as directly #52

Merged
merged 3 commits into from
Nov 10, 2020
Merged

Conversation

regadas
Copy link
Collaborator

@regadas regadas commented Nov 8, 2020

No description provided.

Copy link
Collaborator

@johnynek johnynek left a comment

Choose a reason for hiding this comment

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

I had a few comments to think about.

One thing: I think the default implementation of replicateA (which uses sequence) might actually be fine in terms of performance and keeps the internals simpler.

/** Replaces parsed values with the given value.
*/
def as[B](b: B): Parser[B] =
Parser.as(this)(b)
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 here we can just do .void.map(_ => b) since this is not fundamental. And remove from the companion.

/** This method override `Parser#replicateA` to refine return type.
*/
override def replicateA(n: Int): Parser1[List[A]] =
Parser.replicateA1(n, this)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This isn't a Parser1 if n == 0, right?

/** This method overrides `Parser#as` to refine the return type.
*/
override def as[B](b: B): Parser1[B] =
Parser.as1(this)(b)
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 void.map is fine.

/** Replaces parsed values with the given value.
*/
def as[A, B](pa: Parser[A])(b: B): Parser[B] =
map(Impl.Void(pa))(_ => b)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually def void does more than this. It also unmaps pa so we can simplify it. We should use that but I think as I mentioned just using the void method is the way to go.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah you are right, it's better to use it.

}
}

case class Replicate1[A, B](p1: Parser1[A], n: Int, acc: Accumulator1[A, B])
Copy link
Collaborator

Choose a reason for hiding this comment

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

What do you think of this idea instead: we take a min and a max in Rep, and for replicate then min is the max. But this also enables a new combinator: parse at most n things. Of course that is a bit of a weird combinator so maybe not with special casing.

/** Apply Parser1 `n` times
*/
def replicateA1[A](n: Int, pa: Parser1[A])(implicit
acc: Accumulator1[A, List[A]]
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 we should just pass the List accumulator and not use an implicit here since it compilcates the call site but does not add power. What do you think?

Alternatively: we make this replicateAs and then allow us to replicate into different types (like Vector)

@johnynek
Copy link
Collaborator

johnynek commented Nov 8, 2020

Thanks for taking this on!

@johnynek
Copy link
Collaborator

johnynek commented Nov 9, 2020

The more I think about it, replicateA is a really bad name. The A comes from the fact that replicate is already a method on collections, IIRC. So, the A stands for applicative. I think maybe .exactly or something might be a better name. I used rep, following fastparse, to mean repeat at least, which is the most common kind of repetition (and almost always you want to repeat 0 or more times, or 1 or more times)...

honestly, maybe we should just punt on the whole replicate question and remove that for now. I can't even imagine a use case at the moment, and if you want it, you can use replicateA from Applicative to get it.

What do you think?

@regadas
Copy link
Collaborator Author

regadas commented Nov 10, 2020

@johnynek I agree with you regarding replicateA, from name to use case, it's a bit weird. Most of the time what we want is really 0/1 or more times so I'm fine in let it rest for now.

I'll clean it up in a bit!

@regadas regadas changed the title Add common Functor#as and Applicative#replicateA directly Add common Functor#as directly Nov 10, 2020
@johnynek
Copy link
Collaborator

Thanks a ton!

I'm going to make one more PR than release a new version today.

@johnynek johnynek merged commit 9f404d9 into typelevel:main Nov 10, 2020
@regadas regadas deleted the 48_as_replicateA branch November 10, 2020 17:05
@rossabaker rossabaker mentioned this pull request Nov 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants