purescript-polyform/polyform

Finish `SignUp` example

Closed this issue · 11 comments

paluh commented
Finish `SignUp` example
paluh commented

@thomashoneyman I've added sign up form to test suite which is tested against Http data source:

https://github.com/paluh/purescript-polyform/blob/master/test/Polyform/Input/Http.purs#L116

I'm going to move this example to docs this weekend.

Thanks @paluh! I've been working on a minimal formlets implementation for Halogen, but if Polyform is able to work well with Halogen, I'd love to contribute to the library. I'll pull it down this weekend and see how far I get. Have you tried this yet?

paluh commented

Unfortunately I'm testing this library on the backend currently (hence Input.Http module ;-)). I'm afraid that in order to use it on frontend or with JSON you have to write your own "data input" like Input.Record or use Input.Interpret and write interpretations... This library is still in beta stage ;-)

But... I want to write simple implementation of #1 so probably I will provide some stub for Input.JSON ;-)

paluh commented

@thomashoneyman This signup form is also quite nice candidate to check if this is feasible with this library #4 because we have "local" passwords and inputs checks and "remote" email check ;-)

Right -- being able to mix monadic / applicative is vital. For us, flexible rendering matters a lot as well, and so the Halogen HTML base is critical.

you have to write your own "data input" like Input.Record or use Input.Interpret and write interpretations

Noted!

paluh commented

I can provide wrapper around Form.Validation (like Form.Validation.Monad.ValidationM) and you are going to get Monad instance but at a price of loosing the accumulative nature of Applicative (side note: I can't provide Monad instance for existing Validation type which wouldn't be compatible with existing Applicative instance). Let's consider two expressions.

Here we have applicative validation in action:

passwordFormA = { password1: _, password2: _ } <$> password1Form <*> password2Form

It appends password1Form "form" and password2Form into single form under the hood (the idea is really taken from purescript-validation) regardless of the first step result (I mean emailForm validation step).

This monadic version (here password1Form and password2Form are hypothetical ValidationM values) behaves differently though:

passwordFormM = do
  password1 <- password1Form
  password2 <- password2Form
  if password1 != password2
    then formError "Passwords don't match"
    else pure { email, password }

It won't append the second "form" from password2Form when password1Form validation fails, because the whole monadic block after password1 <- password1Form can depend on the password1 value so there is no way to continue when password1Form fails. In other words you won't get the whole "form" value (which you probably want to render) and you won't get all errors (because it would stop on the first).

This library solves this problem by providing Category instance (expanded version ;-)):

passwordFormA >>> (Validation $ \{ password1, password2 } ->
  pure $ if password1 != password2
    -- I don't now here exact structure of your possible form so I'm using hypothetical heper
    then Invalid (errorForm "Passwords don't match")
    else Valid mempty password1

what would be great is mixing the two with https://pursuit.purescript.org/packages/purescript-parallel/3.2.0/docs/Control.Parallel#t:Parallel:

liftPar2 f a b = sequential $ lift2 f (parallel a) (parallel b)

passwordFormM = do
  { password1, password2 } <- liftPar2 { password1: _, password2: _ } password1Form password2Form
  if password1 != password2
    then formError "Passwords don't match"
    else pure password1
paluh commented

@MonoidMusician This is really cool idea. I'm going to look into that and try to provide appropriate instances!

paluh commented

I'm still not sure if I should provide ValidationM wrapper for Form.Validation, but here is a type which provides parallel wrapper for our Applicative version:

https://github.com/paluh/purescript-polyform/blob/master/src/Polyform/Form/Validation/Par.purs

paluh commented

I'm closing this in favour of #5