-
Notifications
You must be signed in to change notification settings - Fork 450
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 ApplicativeError example to Validated docs #847
Conversation
data class FormField(val label: String, val value: String) | ||
data class Email(val value: String) | ||
|
||
abstract class Rules<F>(val A: ApplicativeError<F, Nel<ValidationError>>) : ApplicativeError<F, Nel<ValidationError>> by A { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A
doesn't have to be a field. Why the abstract class and not interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is nothing to implement, therefore no need for an interface and if it were an interface
then it results in more boilerplate in the interpreters.
interface Rules<F> : ApplicativeError<F, Nel<ValidationError>> {
val A: ApplicativeError<F, Nel<ValidationError>>
private fun FormField.contains(needle: String): Kind<F, FormField> =
if (value.contains(needle, false)) just(this)
else raiseError(DoesNotContain(needle).nel())
private fun FormField.maxLength(maxLength: Int): Kind<F, FormField> =
if (value.length <= maxLength) just(this)
else raiseError(MaxLength(maxLength).nel())
fun FormField.validateEmail(): Kind<F, Email> =
map(contains("@"), maxLength(250), {
Email(value)
}).handleErrorWith { raiseError(NotAnEmail(it).nel()) }
}
val errorAccumulatingApplicative : ApplicativeError<ValidatedPartialOf<Nel<ValidationError>>, Nel<ValidationError>> =
Validated.applicativeError(NonEmptyList.semigroup())
object ErrorAccumulationStrategy :
Rules<ValidatedPartialOf<Nel<ValidationError>>>,
ApplicativeError<ValidatedPartialOf<Nel<ValidationError>>, Nel<ValidationError>> by errorAccumulatingApplicative {
override val A: ApplicativeError<ValidatedPartialOf<Nel<ValidationError>>, Nel<ValidationError>>
get() = Validated.applicativeError(NonEmptyList.semigroup())
}
Normally in tagless the practice I see is that if you can implement the algebra entirely with a type class and not leave any methods abstract to the interpreters then you don't need to use an interface or trait since the very definition of the algebra is abstract by relying on the type classes.
@@ -214,6 +214,79 @@ val houseNumber = config.parse(Read.intRead, "house_number").withEither { either | |||
houseNumber | |||
``` | |||
|
|||
## Abstracting aways validation strategies with `ApplicativeError` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternative validation strategies to Validated
: using ApplicativeError
? It's a bit more specific than abstracting away
. It'd be worthwhile to have a version of this example on the ApplicativeError docs!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just a couple of comments.
} | ||
``` | ||
|
||
`Rules` defines abstract behaviors that can be composed and have access to the scoipe of `ApplicativeError` where we can invoke `just` to lift values in to the positive result and `raiseError` into the error context. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: scoipe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how easy this snippet is to follow for someone starting out with Arrow. Any1 we can ask?
Validated
is a good candidate for new people from coming to OOP so they should be able to follow this snippet easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how easy this snippet is to follow for someone starting out with Arrow. Any1 we can ask?
Validated
is a good candidate for new people from coming to OOP so they should be able to follow this snippet easily.
@nomisRev This example is considered advanced in the context that it requires a bit of knowledge on how Applicative and Applicative Error works though it contains a brief paragraph explaining how they are used in this context:
Are you implying we should not add it to the docs in Validated? |
No, I was not implying that at all. Just wondering if we could add something to mark it as advanced and/or point to Applicative/ApplicativeError. Marking snippets or part of documentation as advanced might make them less intimidating/demotivating for new people. |
@nomisRev Added an issue to discuss with @israelperezglez @calvellido . Feel free to contribute any ideas or thoughts there and we can address this in general for all docs since this same jump from beginner to advance happens in many other places. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also include some links to this on the Error Handling pattern section?
Codecov Report
@@ Coverage Diff @@
## master #847 +/- ##
=========================================
Coverage 44.41% 44.41%
Complexity 633 633
=========================================
Files 294 294
Lines 7459 7459
Branches 834 834
=========================================
Hits 3313 3313
Misses 3844 3844
Partials 302 302 Continue to review full report at Codecov.
|
…be memory related.
Thanks :-) |
* Update README.md * code review * code review * Update README.md * code review * Update README.md * fix code snippets missing `)` * Examples in ApplicativeError and ErrorHandling docs. Ank chockes, maybe memory related.
This example shows how you can abstract away failure strategies