We're happy to Announce Thin Backend - a blazing fast, universal web app backend for making realtime SPAs

Validation with monadic operations

Fidel

When using withCustomErrorMessageIO, it adds the custom error message to whatever error happens to be there... That is, if I do:

...   
   |> validateField #name nonEmpty
   |> withCustomErrorMessageIO "Name is already taken" validateIsUnique #name

when the field is empty, instead of printing the error "This field cannot be empty", it prints "Name already taken". And if I invert the order, I need to add a return, because validateField does not return a monad, as in:

...
   |> withCustomErrorMessageIO "Name is already taken" validateIsUnique #name
   >>= return . validateField #name nonEmpty

Is there some better solution to this problem?

marc PRO

There's no better solution than the return . approach currently. We have a couple of combinators like validateAll, but those only with pure non-IO validations.

Btw: In IHP we generally prefer pure over return as return can be confusing to people coming from other programming languages :)

Fidel

Ok. It should be nice to have some combinator that abstracts this ... >>= pure . ... part... Something as:

infixl 8 |=>

(|=>) :: IO model -> (model -> model) -> IO model 
(|=>) iomodel validator = iomodel >>= (pure . validator)
marc PRO

Created a github issue for this https://github.com/digitallyinduced/ihp/issues/1383

Fidel

You get my idea quicker than myself... :P To complete the thread, the final code will be something as:

...
   |> withCustomErrorMessageIO "Name is already taken" validateIsUnique #name
   |=> validateField #name nonEmpty
Daniel Sokil PRO

For future reference, now we have an |>> operator:

...
   |> withCustomErrorMessageIO "Name is already taken" validateIsUnique #name
   |>> validateField #name nonEmpty
Fidel

Excelent. Thanks