Refactor of validate/coerce

In previous iterations, coercion and validation were kept separate. However, it's become apparent this was the wrong approach. Matching a constraint definition to a corresponding data structure requires it to be validated, and likewise certain validations rely on previous transformations.

For example:

    (I Integer (min-value 0))

The coercion to an integer must take place before the min-value coercion is applied. Likewise:

    (U UUID Integer)

The validation must take place to determine the type, and therefore the coercion to be applied.

Because of this inherent mix, this PR refactors the code to designate a `Transform` protocol that we can derive both `validate` and `coerce` from.