-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | ditto is a type-safe HTML form generation and validation library -- -- ditto follows in the footsteps of formlets and digestive-functors -- <= 0.2. It provides a type-safe and composable method for -- generating an HTML form that includes validation. @package ditto @version 0.3 -- | Module for the core result type, and related functions module Ditto.Result -- | Type for failing computations data Result e ok Error :: [(FormRange, e)] -> Result e ok Ok :: ok -> Result e ok -- | convert a Result to Maybe discarding the error message -- on Error getResult :: Result e ok -> Maybe ok -- | An ID used to identify forms data FormId FormId :: String -> NonEmpty Int -> FormId FormIdCustom :: String -> Int -> FormId -- | The zero ID, i.e. the first ID that is usable zeroId :: String -> FormId -- | map a function over the NonEmpty Int inside a FormId mapId :: (NonEmpty Int -> NonEmpty Int) -> FormId -> FormId -- | A range of ID's to specify a group of forms data FormRange FormRange :: FormId -> FormId -> FormRange -- | Increment a form ID incrementFormId :: FormId -> FormId -- | create a FormRange from a FormId unitRange :: FormId -> FormRange -- | Check if a FormId is contained in a FormRange isInRange :: FormId -> FormRange -> Bool -- | Check if a FormRange is contained in another FormRange isSubRange :: FormRange -> FormRange -> Bool -- | Select the errors for a certain range retainErrors :: FormRange -> [(FormRange, e)] -> [e] -- | Select the errors originating from this form or from any of the -- children of this form retainChildErrors :: FormRange -> [(FormRange, e)] -> [e] instance GHC.Base.Functor (Ditto.Result.Result e) instance (GHC.Classes.Eq e, GHC.Classes.Eq ok) => GHC.Classes.Eq (Ditto.Result.Result e ok) instance (GHC.Show.Show e, GHC.Show.Show ok) => GHC.Show.Show (Ditto.Result.Result e ok) instance GHC.Show.Show Ditto.Result.FormRange instance GHC.Classes.Eq Ditto.Result.FormRange instance GHC.Classes.Ord Ditto.Result.FormId instance GHC.Classes.Eq Ditto.Result.FormId instance GHC.Base.Monad (Ditto.Result.Result e) instance GHC.Base.Applicative (Ditto.Result.Result e) instance GHC.Show.Show Ditto.Result.FormId -- | This module defines the Form type, its instances, core -- manipulation functions, and a bunch of helper utilities. module Ditto.Core -- | Proved records a value, the location that value came from, and -- something that was proved about the value. data Proved a Proved :: FormRange -> a -> Proved a [pos] :: Proved a -> FormRange [unProved] :: Proved a -> a -- | Utility Function: trivially prove nothing about () unitProved :: FormId -> Proved () -- | inner state used by Form. type FormState m input = ReaderT (Environment m input) (StateT FormRange m) -- | used to represent whether a value was found in the form submission -- data, missing from the form submission data, or expected that the -- default value should be used data Value a Default :: Value a Missing :: Value a Found :: a -> Value a -- | Utility function: Get the current input getFormInput :: Monad m => FormState m input (Value input) -- | Utility function: Gets the input of an arbitrary FormId. getFormInput' :: Monad m => FormId -> FormState m input (Value input) -- | Utility function: Get the current range getFormRange :: Monad m => FormState m i FormRange -- | The environment is where you get the actual input per form. -- -- The NoEnvironment constructor is typically used when generating -- a view for a GET request, where no data has yet been submitted. This -- will cause the input elements to use their supplied default values. -- -- Note that NoEnviroment is different than supplying an empty -- environment. data Environment m input Environment :: (FormId -> m (Value input)) -> Environment m input NoEnvironment :: Environment m input -- | Utility function: returns the current FormId. This will only -- make sense if the form is not composed getFormId :: Monad m => FormState m i FormId getNamedFormId :: Monad m => String -> FormState m i FormId -- | Utility function: increment the current FormId. incFormId :: Monad m => FormState m i () -- | A view represents a visual representation of a form. It is composed of -- a function which takes a list of all errors and then produces a new -- view newtype View err v View :: ([(FormRange, err)] -> v) -> View err v [unView] :: View err v -> [(FormRange, err)] -> v -- | a Form contains a View combined with a validation -- function which will attempt to extract a value from submitted form -- data. -- -- It is highly parameterized, allowing it work in a wide variety of -- different configurations. You will likely want to make a type alias -- that is specific to your application to make type signatures more -- manageable. -- -- -- -- This type is very similar to the Form type from -- digestive-functors <= 0.2. If proof is -- (), then Form is an applicative functor and can be -- used almost exactly like digestive-functors <= 0.2. newtype Form m input err view a Form :: FormState m input (View err view, m (Result err (Proved a))) -> Form m input err view a [unForm] :: Form m input err view a -> FormState m input (View err view, m (Result err (Proved a))) bracketState :: Monad m => FormState m input a -> FormState m input a -- | This provides a Monad instance which will stop rendering on err. This -- instance isn't a part of Form because of its undesirable -- behavior. -XApplicativeDo is generally preferred newtype MForm m input err view a MForm :: Form m input err view a -> MForm m input err view a [runMForm] :: MForm m input err view a -> Form m input err view a runAsMForm :: Monad m => Environment m input -> Text -> Form m input err view a -> m (View err view, m (Result err (Proved a))) -- | Run a form runForm :: Monad m => Environment m input -> Text -> Form m input err view a -> m (View err view, m (Result err (Proved a))) -- | Run a form runForm' :: Monad m => Environment m input -> Text -> Form m input err view a -> m (view, Maybe a) -- | Just evaluate the form to a view. This usually maps to a GET request -- in the browser. viewForm :: Monad m => Text -> Form m input err view a -> m view -- | Evaluate a form -- -- Returns: -- -- eitherForm :: Monad m => Environment m input -> Text -> Form m input err view a -> m (Either view a) -- | create a Form from some view. -- -- This is typically used to turn markup like <br> into a -- Form. view :: Monad m => view -> Form m input err view () -- | Append a unit form to the left. This is useful for adding labels or -- err fields. -- -- The Forms on the left and right hand side will share the same -- FormId. This is useful for elements like <label -- for="someid">, which need to refer to the id of another -- element. (++>) :: (Monad m, Semigroup view) => Form m input err view z -> Form m input err view a -> Form m input err view a infixl 6 ++> -- | Append a unit form to the right. See ++>. (<++) :: (Monad m, Semigroup view) => Form m input err view a -> Form m input err view z -> Form m input err view a infixr 5 <++ -- | Change the view of a form using a simple function -- -- This is useful for wrapping a form inside of a <fieldset> or -- other markup element. mapView :: Functor m => (view -> view') -> Form m input err view a -> Form m input err view' a -- | infix mapView: succinct `foo @$ do ..` (@$) :: Monad m => (view -> view) -> Form m input err view a -> Form m input err view a infixr 0 @$ -- | Utility Function: turn a view and pure value into a successful -- FormState mkOk :: Monad m => FormId -> view -> a -> FormState m input (View err view, m (Result err (Proved a))) instance (GHC.Base.Monoid view, GHC.Base.Monad m) => GHC.Base.Applicative (Ditto.Core.MForm m input err view) instance (GHC.Base.Monad m, GHC.Base.Monoid view) => GHC.Base.Alternative (Ditto.Core.MForm m input err view) instance GHC.Base.Functor m => Data.Bifunctor.Bifunctor (Ditto.Core.MForm m input err) instance GHC.Base.Functor m => GHC.Base.Functor (Ditto.Core.MForm m input err view) instance GHC.Base.Functor m => GHC.Base.Functor (Ditto.Core.Form m input err view) instance GHC.Base.Functor (Ditto.Core.View err) instance GHC.Base.Monoid v => GHC.Base.Monoid (Ditto.Core.View err v) instance GHC.Base.Semigroup v => GHC.Base.Semigroup (Ditto.Core.View err v) instance GHC.Base.Functor Ditto.Core.Proved instance GHC.Show.Show a => GHC.Show.Show (Ditto.Core.Proved a) instance (GHC.Base.Monad m, GHC.Base.Monoid view) => GHC.Base.Monad (Ditto.Core.MForm m input err view) instance (GHC.Base.Functor m, GHC.Base.Monoid view, GHC.Base.Monad m) => GHC.Base.Applicative (Ditto.Core.Form m input err view) instance (GHC.Base.Monad m, GHC.Base.Monoid view) => GHC.Base.Alternative (Ditto.Core.Form m input err view) instance GHC.Base.Functor m => Data.Bifunctor.Bifunctor (Ditto.Core.Form m input err) instance (GHC.Base.Monad m, GHC.Base.Monoid view, GHC.Base.Semigroup a) => GHC.Base.Semigroup (Ditto.Core.Form m input err view a) instance (GHC.Base.Monoid view, GHC.Base.Monad m, GHC.Base.Semigroup a) => GHC.Base.Monoid (Ditto.Core.Form m input err view a) instance (GHC.Base.Semigroup input, GHC.Base.Monad m) => GHC.Base.Semigroup (Ditto.Core.Environment m input) instance (GHC.Base.Semigroup input, GHC.Base.Monad m) => GHC.Base.Monoid (Ditto.Core.Environment m input) -- | This module defines the Proof type, some proofs, and some -- helper functions. -- -- A Proof does three things: -- -- module Ditto.Proof -- | A Proof attempts to prove something about a value. -- -- If successful, it can also transform the value to a new value. The -- proof should hold for the new value as well. -- -- Generally, each Proof has a unique data-type associated with it -- which names the proof, such as: newtype Proof m error a b Proof :: (a -> m (Either error b)) -> Proof m error a b -- | function which provides the proof [proofFunction] :: Proof m error a b -> a -> m (Either error b) -- | apply a Proof to a Form prove :: Monad m => Form m input error view a -> Proof m error a b -> Form m input error view b -- | transform a Form using a Proof, and the replace the -- proof with (). -- -- This is useful when you want just want classic digestive-functors -- behaviour. transform :: Monad m => Form m input error view a -> Proof m error a b -> Form m input error view b -- | transform the Form result using a monadic Either -- function. transformEitherM :: Monad m => Form m input error view a -> (a -> m (Either error b)) -> Form m input error view b -- | transform the Form result using an Either function. transformEither :: Monad m => Form m input error view a -> (a -> Either error b) -> Form m input error view b -- | prove that a list is not empty notNullProof :: Monad m => error -> Proof m error [a] [a] -- | read an unsigned number in decimal notation decimal :: (Monad m, Eq i, Num i) => (String -> error) -> Proof m error String i -- | read signed decimal number signedDecimal :: (Monad m, Eq i, Real i) => (String -> error) -> Proof m error String i -- | read RealFrac number realFrac :: (Monad m, RealFrac a) => (String -> error) -> Proof m error String a -- | read a signed RealFrac number realFracSigned :: (Monad m, RealFrac a) => (String -> error) -> Proof m error String a -- | This module contains two classes. FormInput is a class which is -- parameterized over the input type used to represent form data -- in different web frameworks. There should be one instance for each -- framework, such as Happstack, Snap, WAI, etc. -- -- The FormError class is used to map error messages into an -- application specific error type. module Ditto.Backend -- | an error type used to represent errors that are common to all backends -- -- These errors should only occur if there is a bug in the ditto-* -- packages. Perhaps we should make them an Exception so that we -- can get rid of the FormError class. data CommonFormError input InputMissing :: FormId -> CommonFormError input NoStringFound :: input -> CommonFormError input NoFileFound :: input -> CommonFormError input MultiFilesFound :: input -> CommonFormError input MultiStringsFound :: input -> CommonFormError input MissingDefaultValue :: CommonFormError input -- | some default error messages for CommonFormError commonFormErrorStr :: (input -> String) -> CommonFormError input -> String -- | some default error messages for CommonFormError commonFormErrorText :: (input -> Text) -> CommonFormError input -> Text -- | A Class to lift a CommonFormError into an application-specific -- error type class FormError err input | err -> input commonFormError :: FormError err input => CommonFormError input -> err -- | Class which all backends should implement. class FormInput input where { -- | input is here the type that is used to represent a value -- uploaded by the client in the request. type family FileType input; } -- | Parse the input into a string. This is used for simple text fields -- among other things getInputString :: (FormInput input, FormError error input) => input -> Either error String -- | Should be implemented getInputStrings :: FormInput input => input -> [String] -- | Parse the input value into Text getInputText :: (FormInput input, FormError error input) => input -> Either error Text -- | Can be overriden for efficiency concerns getInputTexts :: FormInput input => input -> [Text] -- | Get a file descriptor for an uploaded file getInputFile :: (FormInput input, FormError error input) => input -> Either error (FileType input) instance GHC.Show.Show input => GHC.Show.Show (Ditto.Backend.CommonFormError input) instance GHC.Classes.Ord input => GHC.Classes.Ord (Ditto.Backend.CommonFormError input) instance GHC.Classes.Eq input => GHC.Classes.Eq (Ditto.Backend.CommonFormError input) instance Ditto.Backend.FormError Data.Text.Internal.Text Data.Text.Internal.Text module Ditto.Generalized.Named -- | used for constructing elements like <input -- type="text">, which pure a single input value. input :: (Monad m, FormError err input) => String -> (input -> Either err a) -> (FormId -> a -> view) -> a -> Form m input err view a -- | used to construct elements with optional initial values, which are -- still required inputMaybeReq :: (Monad m, FormError err input) => String -> (input -> Either err a) -> (FormId -> Maybe a -> view) -> Maybe a -> Form m input err view a -- | used for elements like <input type="submit"> which are -- not always present in the form submission data. inputMaybe :: (Monad m, FormError err input) => String -> (input -> Either err a) -> (FormId -> Maybe a -> view) -> Maybe a -> Form m input err view (Maybe a) -- | used for elements like <input type="reset"> which take -- a value, but are never present in the form data set. inputNoData :: Monad m => String -> (FormId -> view) -> Form m input err view () -- | used for <input type="file"> inputFile :: forall m input err view. (Monad m, FormInput input, FormError err input) => String -> (FormId -> view) -> Form m input err view (FileType input) -- | used for groups of checkboxes, <select -- multiple="multiple"> boxes inputMulti :: forall m input err view a lbl. (FormError err input, FormInput input, Monad m) => String -> [(a, lbl)] -> (FormId -> [(FormId, Int, lbl, Bool)] -> view) -> (a -> Bool) -> Form m input err view [a] -- | radio buttons, single <select> boxes inputChoice :: forall a m err input lbl view. (FormError err input, FormInput input, Monad m) => String -> (a -> Bool) -> [(a, lbl)] -> (FormId -> [(FormId, Int, lbl, Bool)] -> view) -> Form m input err view a -- | radio buttons, single <select> boxes inputChoiceForms :: forall a m err input lbl view. (Monad m, FormError err input, FormInput input) => String -> a -> [(Form m input err view a, lbl)] -> (FormId -> [(FormId, Int, FormId, view, lbl, Bool)] -> view) -> Form m input err view a -- | used to create <label> elements label :: Monad m => String -> (FormId -> view) -> Form m input err view () -- | used to add a list of err messages to a Form -- -- This function automatically takes care of extracting only the errors -- that are relevent to the form element it is attached to via -- <++ or ++>. errors :: Monad m => ([err] -> view) -> Form m input err view () -- | similar to errors but includes err messages from children of -- the form as well. childErrors :: Monad m => ([err] -> view) -> Form m input err view () -- | modify the view of a form based on its errors withErrors :: Monad m => (view -> [err] -> view) -> Form m input err view a -> Form m input err view a module Ditto.Generalized -- | used for constructing elements like <input -- type="text">, which pure a single input value. input :: (Monad m, FormError err input) => (input -> Either err a) -> (FormId -> a -> view) -> a -> Form m input err view a -- | used for elements like <input type="submit"> which are -- not always present in the form submission data. inputMaybe :: (Monad m, FormError err input) => (input -> Either err a) -> (FormId -> Maybe a -> view) -> Maybe a -> Form m input err view (Maybe a) -- | used to construct elements with optional initial values, which are -- still required inputMaybeReq :: (Monad m, FormError err input) => (input -> Either err a) -> (FormId -> Maybe a -> view) -> Maybe a -> Form m input err view a -- | used for elements like <input type="reset"> which take -- a value, but are never present in the form data set. inputNoData :: Monad m => (FormId -> view) -> Form m input err view () -- | used for <input type="file"> inputFile :: forall m input err view. (Monad m, FormInput input, FormError err input) => (FormId -> view) -> Form m input err view (FileType input) -- | used for groups of checkboxes, <select -- multiple="multiple"> boxes inputMulti :: forall m input err view a lbl. (FormError err input, FormInput input, Monad m) => [(a, lbl)] -> (FormId -> [(FormId, Int, lbl, Bool)] -> view) -> (a -> Bool) -> Form m input err view [a] -- | radio buttons, single <select> boxes inputChoice :: forall a m err input lbl view. (FormError err input, FormInput input, Monad m) => (a -> Bool) -> [(a, lbl)] -> (FormId -> [(FormId, Int, lbl, Bool)] -> view) -> Form m input err view a -- | radio buttons, single <select> boxes inputChoiceForms :: forall a m err input lbl view. (Monad m, FormError err input, FormInput input) => a -> [(Form m input err view a, lbl)] -> (FormId -> [(FormId, Int, FormId, view, lbl, Bool)] -> view) -> Form m input err view a -- | used to create <label> elements label :: Monad m => (FormId -> view) -> Form m input err view () -- | used to add a list of err messages to a Form -- -- This function automatically takes care of extracting only the errors -- that are relevent to the form element it is attached to via -- <++ or ++>. errors :: Monad m => ([err] -> view) -> Form m input err view () -- | similar to errors but includes err messages from children of -- the form as well. childErrors :: Monad m => ([err] -> view) -> Form m input err view () -- | modify the view of a form based on its errors withErrors :: Monad m => (view -> [err] -> view) -> Form m input err view a -> Form m input err view a module Ditto