Closed mavenraven closed 10 years ago
It's not possible (in a nice and composable way) to add a Monad
instance for a form. This is discussed in the paper The Essence of Form Abstraction, the original paper that inspired formlet-like libraries.
What sort of validation are you trying to implement? There might be another trick to do it.
I think the best way to do what I want is something like this:
needsConfirmation :: (MonadState s m) => (a -> s) -> Form T.Text m a -> Form T.Text m a
needsConfirmation f = validateM g
where g a = do {
put (f a);
return (Success a);
}
confirms :: (MonadState s m, Eq a) => (s -> a) -> Form T.Text m a -> Form T.Text m a
confirms f = validateM g
where g a = do {
s <- get;
if ((f s) == a)
then return $ Success a
else return $ Error "not equal!"
}
I was trying to avoid using validateM for this, because it means I have to a StateT on top of Handler in Snap, and the user has to specify paths through the state to the value they want, but I don't really have anything better.
Hey, so I've looking into adding a confirmation validator to digestive-functors-validations that would work similar to Active Record confirmations .
This looks like it needs a Monad instance for FormTree, so I've looked into adding that. The problem is that some of the helper functions are impossible to make the type system unify (I think). For example, if
, then for
we start with
and we need to get our type to
. So,
must be
or
where
. The only way we have to get from
is to use
that we're given by y. But, we have no way of getting from
only
, so it doesn't look possible, at least not without changing the type signature. But the only place formMapView is used is for a Functor instance, so even that doesn't help. I was thinking of adding a new type called MonadFormTree and a runMonadFormTree that would let you get back to a regular FormTree. Seems kind of ugly though. Any thoughts?