ozmat/elm-validation/2.1.0

NOTE: this package is not compatible with Elm 0.19.1

Validation

This library aims to provide basic Validation in Elm

ValidationError

= Error err
| ErrorList (List err)

A ValidationError can be a simple Error or an ErrorList

type YourError
    = ErrorX
    | ErrorY String Int


Error ErrorX


Error (ErrorY "some message" 15)


ErrorList [ ErrorX, ErrorY "some message" 15 ]

Common Helpers

append : ValidationError err -> ValidationError err -> ValidationError err

Combines two ValidationError

append (Error 1) (Error 2)
    |> Expect.equal (ErrorList [ 1, 2 ])


append (Error 1) (ErrorList [ 2, 3 ])
    |> Expect.equal (ErrorList [ 1, 2, 3 ])


append (ErrorList [ 2, 3 ]) (Error 1)
    |> Expect.equal (ErrorList [ 1, 2, 3 ])


append (ErrorList [ 1, 2 ]) (ErrorList [ 3, 4 ])
    |> Expect.equal (ErrorList [ 1, 2, 3, 4 ])
errorToList : ValidationError err -> List err

Converts a ValidationError into a List err

errorToList (Error 1)
    |> Expect.equal [ 1 ]


errorToList (ErrorList [ 1, 2, 3 ])
    |> Expect.equal [ 1, 2, 3 ]

Map

errorMap : (err1 -> err2) -> ValidationError err1 -> ValidationError err2

Map a function over a ValidationError

errorMap ((+) 1) (Error 1)
    |> Expect.equal (Error 2)


errorMap ((+) 1) (ErrorList [ 1, 2, 3 ])
    |> Expect.equal (ErrorList [ 2, 3, 4 ])

Validation

type Validation err a
= Failure (ValidationError err)
| Success a

A Validation can be a Success or a Failure

Success "output value"


Failure (Error "not valid")


Failure (ErrorList ["too short", "forbidden character"])

Common Helpers

success : a -> Validation err a

Returns a successful Validation

success "output value"
    |> Expect.equal (Success "output value")
failure : err -> Validation err a

Returns a failed Validation

failure "not valid"
    |> Expect.equal (Failure (Error "not valid"))
failureWithList : List err -> Validation err a

Returns a failed Validation with an ErrorList

failureWithList ["error1", "error2"]
    |> Expect.equal (Failure (ErrorList ["error1", "error2"]))
validation : err -> (a -> Bool) -> a -> Validation err a

Helps creating a basic Validation function

type YourError
    = ErrorX


emptyValidation : String -> Validation YourError String
emptyValidation =
    validation ErrorX String.isEmpty


emptyValidation ""
    |> Expect.equal (Success "")


emptyValidation "notempty"
    |> Expect.equal (Failure (Error ErrorX ))
toResult : Validation err a -> Result (List err) a

Converts a Validation to a Result

toResult (Success "valid")
    |> Expect.equal (Ok "valid")


toResult (Failure (Error "error"))
    |> Expect.equal (Err [ "error" ])
toList : Validation err a -> List err

Converts a Validation to a List. The List is empty if it's a successful validation or contains the errors if it's failed validation.

toList (Success "valid")
    |> Expect.equal ([])


toList (Failure (Error "error"))
    |> Expect.equal ([ "error" ])

Map

map : (a -> b) -> Validation err a -> Validation err b

Map a function over a successful Validation

map ((+) 1) (Success 1)
    |> Expect.equal (Success 2)


map ((+) 1) (Error 1)
    |> Expect.equal (Error 1)
mapError : (err1 -> err2) -> Validation err1 a -> Validation err2 a

Map a function over a failed Validation

mapError ((+) 1) (Success 1)
    |> Expect.equal (Success 1)


mapError ((+) 1) (Failure (Error 1))
    |> Expect.equal (Failure (Error 2))


mapError ((+) 1) (Failure (ErrorList [ 1, 2 ]))
    |> Expect.equal (Failure (ErrorList [ 2, 3 ]))
(ValidationError err1 -> ValidationError err2)
-> Validation err1 a
-> Validation err2 a

Map a function over a failed Validation on the ValidationError

tranform : ValidationError Int -> ValidationError Int
tranform v =
    case v of
        Error n ->
            ErrorList (List.repeat 5 n)


        ErrorList l ->
            ErrorList l


mapValidationError tranform (Success 1)
    |> Expect.equal (Success 1)


mapValidationError tranform (Failure (Error 1))
    |> Expect.equal (Failure (ErrorList [ 1, 1, 1, 1, 1 ]))

Chaining

andMap : Validation err a -> Validation err (a -> b) -> Validation err b

Chain together many Validation by binding them. This means we only continue if the validations are successful and we stop at the first Failure

type alias Example =
    { a : String
    , b : String
    }


success Example
    |> andMap (success "valid1")
    |> andMap (success "valid2")
    |> Expect.equal (Success (Example "valid1" "valid2"))


success Example
    |> andMap (failure "error1")
    |> andMap (success "valid2")
    |> Expect.equal (failure "error1")


success Example
    |> andMap (success "valid1")
    |> andMap (failure "error2")
    |> Expect.equal (failure "error2")


success Example
    |> andMap (failure "error1")
    |> andMap (failure "error2")
    |> Expect.equal (failure "error1")
andMapAcc : Validation err a -> Validation err (a -> b) -> Validation err b

Chain together many Validation by accumulating them. This means we always continue and accumulate all the Failures

type alias Example =
    { a : String
    , b : String
    }


success Example
    |> andMapAcc (success "valid1")
    |> andMapAcc (success "valid2")
    |> Expect.equal (Success (Example "valid1" "valid2"))


success Example
    |> andMapAcc (failure "error1")
    |> andMapAcc (success "valid2")
    |> Expect.equal (failure "error1")


success Example
    |> andMapAcc (success "valid1")
    |> andMapAcc (failure "error2")
    |> Expect.equal (failure "error2")


success Example
    |> andMapAcc (failure "error1")
    |> andMapAcc (failure "error2")
    |> Expect.equal (Failure (ErrorList [ "error2", "error1" ]))