Slides from my presentation at Montpellier JUG about Validation in Functional Programming. Ranging from OOP & JSR 303 to FP with Validated data type, Applicative type class. Includes a short introduction to refined types.
6. JSR 303 results : the good
( Accumulates the errors for us in :
Set<ConstraintViolation<… >>
( Automatic 400 Bad Requests (although this is mostly
done by Spring)
( Support for basic use cases
7. JSR 303 results : the bad
) No support for the parse error of HostAndPort
) Need custom handling for inter-dependent fields
) Annotations are not type-checked
) Weird mix of custom/covered cases
) Smelling reflection down there…
8. JSR 303 results : the weirdo
🤔 Automatic translation of error messages
Why is presentation even related to Validation ???
*
10. Do It Yourself 🛠
Let’s go back to the essence of our problem…
11. Validating one
• Result of a validation is either an error or a value
• Validation is just the function producing that result
• It looks like Optional structure but with an error type
• We need a way to use the validated result
12. Validated ✅ (Kotlin style)
sealed class Validated<E, V> {
data class Valid<E,V>(val value: V) :
Validated<E,V>()
data class Invalid<E, V>(val error: E):
Validated<E, V>()
}
13. So far…
We can :
• create a validated with success with Valid(a)
• create a validated with error with Invalid(e)
• map over a Valid value
14. Representing errors
• Let’s use an ADT. In Kotlin :
sealed class AlertCreationError {
data class ThresholdATooLow( /* ... */):
AlertCreationError()
data class ThresholdCTooHigh( /* ... */):
AlertCreationError()
data class ThresholdBNotInBetween(
/* ... */): AlertCreationError()
// And so on
}
15. So far…
We can :
• create a validated with success with Valid(a)
• create a validated with error with Invalid(e)
• map over a Valid value
• fix the type of field validation to
Validated<AlertCreationError, T>
16. Validating many 🤔
• Finding a way to compose validation errors
• Finding a way to compose valid results
We need Composition !
17. Error Accumulation 📋
• JSR 303 used a Set
• When in error, we will at least have one element
• Let’s add some precision
18. NonEmpty*
• Two types exists
• NonEmptyList (NEL)
• NonEmptyChain (NEC)
• Structures which looks like a linked list
but which contains at least one element
• Ensuring this condition via smart constructor
19. Keeping Validated generic
• We need the E type in Validated<E, R> to be
combinable
• That is a function combine: (E, E) -> E
• In the jargon, it is called Semigroup
• We need to go from
Validated<E, R> to Validated<Nel<E>, R>
20. So far…
We can :
• create a validated with success with Valid(a)
• create a validated with error with Invalid(e)
• map over a Valid value
• fix the type of field validation to
Validated<AlertCreationError, T>
• lift the error type from E to Nel<E> (mapLeft)
21. Validating many
• Validating A is independent of validating B
• We need a function, with the shape :
(F<A>,F<B>,(A,B) -> C) -> F<C>
• Where F is a type like Validated with a fixed type
• In the jargon, this is called Applicative
22. So far…
We can :
• create a validated with success with Valid(a)
• create a validated with error with Invalid(e)
• map over a Valid value
• fix the type of field validation to
Validated<AlertCreationError, T>
• lift the error type from E to Nel<E> & accumulate errors
• Combine all values when all fields are in Valid state
• Keep invalid when at least one field is in Invalid state
25. Take away 🥡🍜
Validation is an easy problem which can be solved with just
2 things :
✓Appropriate data structures (some may say ADT) to
model errors & to model validation results
✓An abstraction to express independent computations
(Applicative)
26. 💡There gotta be a
better way ! 🤔
(Again & again !!!)
This is nice and all but…
27. Can we go further ? 🚀
• 💡We could try to make impossible states
unrepresentable
• There is this thing called Refined
• Let’s see some Scala…
(sorry I’m not fluent in Haskell 🙊)
29. Not there yet ! 💫
• Clearly I’m not an expert (but if you are, let’s talk 🤩)
• Even for a simple case like Validation research is
important
• Mathematics are the (best) base tool at hand