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?
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)
Created a github issue for this https://github.com/digitallyinduced/ihp/issues/1383
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
For future reference, now we have an |>> operator:
...
|> withCustomErrorMessageIO "Name is already taken" validateIsUnique #name
|>> validateField #name nonEmpty
Excelent. Thanks

There's no better solution than the
return .approach currently. We have a couple of combinators likevalidateAll, but those only with pure non-IO validations.Btw: In IHP we generally prefer
pureoverreturnasreturncan be confusing to people coming from other programming languages :)