Fork me on GitHub

Maybe I'm misunderstanding how to use applicatives, but here it goes. I have something like (m/<$> validation-fn (m/ok value-to-validate)) and I want it to return (m/fail {:some #{:error}}) when validation-fn fails and (m/ok validated-value) - that is validation-fn could change the constructor from ok to fail if the validation failed; but if I try to return m/ok / m/fail from the validation-fn m/<$> just wraps that again resulting in #<Ok #<Ok ...>> or #<Ok #<Fail ...>>.


Is there anything that would make sense in such context or am I approaching it from a wrong angle?


My idea is to do be able to and those validations so they can act on previous values; for example there would be integer? which would validate whether the value is an integer and/or coercer it, so for (m/ok "12") you'll get (m/ok 12) (or (m/fail #{:not-integer}) when not an integer) and then you could pass it to, say between? that would check whether the value fits in some range and either return (m/ok 12) again or (m/fail #{[:not-between min max]}).


But however I try it, I just seem to nest the wrappers.


Maybe I should just not try to string it like that, but create separate instances for each of validator and or/ and composition; I'll see if I can come up with something meaningful


Now that I think about it


It seems I just want a monad


I think that you are approaching it in a wrong way, let me explain it


You ara putting the validation function into the applicative fapply...


but is wrong, you should create a bunch of "validation functions" that return ok, or fail


and then use the applicative composition for just "join" all validations in one


collectiing it output


Yes, I'm doing something like right now and it works, but it has one downside, unless I'm missing something


Sure, we had plans in the past build a validation library basing on the cats applicative foundation, but we havent had enough time for it


so I don't know at this moment if the validation impl/approach is good enough for solve all cases


Yeah, possibly; I probably should have used bouncer or something, but thought this would be fun to try.


in fact I'm mayself using bouncer on my applications


Basically my issue is I can do

((integer?) "12")
=> #<Ok #validators.core.ResultContainer{:v 12}>
((between? 10 14) 12)
=> #<Ok #validators.core.ResultContainer{:v 12}>
and it works, but I'm then not sure how to chain those two; so I can use between? on the result of integer? so they can both coerce and validate.


This all started because I couldn't figure how to make bouncer not short-circuit validations, but maybe it's just wrongheaded and I should just use it, instead of trying to figure it out '


I'll just probably use bouncer for now and come back to this later when I have more time. Thanks for all the help!