Applicative example - registration form validation
Let's define a simplified class to represent a few fields rudimentary fields on a registration form; less fields to keep the code blocks small, because this is more about the technique that the applicative makes possible, than the accuracy of fields that many registration form employ.
PHP:
case class Account(val id: Int, email: String)
Example of applicative data entry
We lift a curried form of the Account initialiser method into a
Option using
Some; because of our
ap method, we can now left to right add the Account parameters in much the same way as we did with the
add function, finally ending up with an instantiated object wrapped in an Option.
Applicative also gives a fail-able initialiser for free
PHP:
pure(Account.curried)
.ap(None)
.ap(pure("[email protected]"))
.debug("Method") // Debug ~> None : Method
If any of the account values were to be invalid i.e. None (or null); the result would be an Option type wrapping None (null). Basically this approach always wraps failures in order to safely deal with them later, as opposed to throwing an exception or crashing the program with an unmanaged null pointer exception.
In the next post we are going to start adding validation to values i.e. did the user enter what was expected.
Optional information about lifters
Before that I'd like to provide some additional explanation about the
Some lifting types that Scala uses to wrap element values in an Option type.
Note:
[table="width: 100%, class: outer_border"]
[tr]
[td]The
Some type in Scala lifts an element into a container type like
Option; these container types serve the purpose of making it easier to apply math type operations (map, flatMap, ...) to our elements (data), but also to add certain behaviours e.g. better handling of
Null Pointer Exceptions
[/td]
[/tr]
[/table]
In other applications of the Applicative algebra we typically define a lifting function called
pure that can lift any value into our container type, for example in Haskel the Applicative is defined as follows:
PHP:
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Don't worry if you can't read Haskell code; I'll step you through it. First thing, a
class is the definition for a type; similar to an interface or trait in other languages (any other differences don't matter here).
The inheritance of features works left to right i.e. the class signature states that
Applicative is a
Functor (i.e. it must also implement the
map method).
Next is
pure; this is a function signature, i.e. without the implementation. Think of it as something similar to an interface or trait for functions. Basically we take a generic value of type '
a' and lift it into a functor of type '
f'. Note: that both Functor and Applicative have been assigned a generic placeholder variable 'f' i.e.
- class Functor f => Applicative f where
This
pure function is our lifter, and does the same job as
Some or
None for the Scala
Option type. i.e. we embed an element in an
Option type.
Next is
(<*>) -- this is just the way that Haskell uses to define the signature for a custom operator i.e.
<*>is synonymous with our function
ap. i.e. we have a computation from generic type
a to
b wrapped in a functor
f which then takes another value
a also wrapped in a functor
f and returns the result
b also wrapped in a functor
f. i.e. this is the same as the signature for Applicative I summarised in this post:
Custom Operator Note:
[table="width: 100%, class: outer_border"]
[tr]
[td]Because Scala can also support custom operators; For interests sake I will also include a separate post, on how we can define and implement this Applicative operator
<*> in Scala to be used as an alternative to the dot method chaining of the
ap method.[/td]
[/tr]
[/table]