-- 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.4.1 -- | Types relevant to forms and their validation. module Ditto.Types -- | An ID used to identify forms data FormId FormId :: {-# UNPACK #-} !Text -> {-# UNPACK #-} !NonEmpty Int -> FormId FormIdName :: {-# UNPACK #-} !Text -> {-# UNPACK #-} !Int -> FormId -- | A range of ID's to specify a group of forms data FormRange FormRange :: FormId -> FormId -> FormRange -- | Encoding a FormId: use this instead of show for the -- name of the input / query string parameter encodeFormId :: FormId -> Text -- | get the head Int from a FormId formIdentifier :: FormId -> Int -- | 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 -- | views, values as a result of the environment, etc. -- -- Function which creates the form view newtype View err v View :: ([(FormRange, err)] -> v) -> View err v [unView] :: View err v -> [(FormRange, err)] -> v -- | 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 -- | Type for failing computations Similar to Either but with an -- accumilating Applicative instance newtype Result e ok Result :: Either [(FormRange, e)] ok -> Result e ok [getResult] :: Result e ok -> Either [(FormRange, e)] ok pattern Error :: forall e ok. [(FormRange, e)] -> Result e ok pattern Ok :: forall e ok. ok -> Result e ok instance GHC.Show.Show Ditto.Types.FormId instance GHC.Classes.Ord Ditto.Types.FormId instance GHC.Classes.Eq Ditto.Types.FormId instance GHC.Show.Show Ditto.Types.FormRange instance GHC.Classes.Eq Ditto.Types.FormRange instance GHC.Base.Functor (Ditto.Types.View err) instance GHC.Base.Monoid v => GHC.Base.Monoid (Ditto.Types.View err v) instance GHC.Base.Semigroup v => GHC.Base.Semigroup (Ditto.Types.View err v) instance Data.Foldable.Foldable Ditto.Types.Value instance Data.Traversable.Traversable Ditto.Types.Value instance GHC.Base.Functor Ditto.Types.Value instance GHC.Show.Show a => GHC.Show.Show (Ditto.Types.Value a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Ditto.Types.Value a) instance GHC.Base.Monad (Ditto.Types.Result e) instance Data.Traversable.Traversable (Ditto.Types.Result e) instance Data.Foldable.Foldable (Ditto.Types.Result e) instance GHC.Base.Functor (Ditto.Types.Result e) instance (GHC.Classes.Eq e, GHC.Classes.Eq ok) => GHC.Classes.Eq (Ditto.Types.Result e ok) instance (GHC.Show.Show e, GHC.Show.Show ok) => GHC.Show.Show (Ditto.Types.Result e ok) instance Data.Traversable.Traversable Ditto.Types.Proved instance Data.Foldable.Foldable Ditto.Types.Proved instance GHC.Base.Functor Ditto.Types.Proved instance GHC.Show.Show a => GHC.Show.Show (Ditto.Types.Proved a) instance GHC.Base.Applicative (Ditto.Types.Result e) instance GHC.Base.Applicative Ditto.Types.Value instance GHC.Base.Alternative Ditto.Types.Value instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Ditto.Types.Value a) instance Data.String.IsString Ditto.Types.FormId -- | 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 input err commonFormError :: FormError input err => 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 input err) => input -> Either err String getInputStrings :: FormInput input => input -> [String] -- | Parse the input value into Text getInputText :: (FormInput input, FormError input err) => input -> Either err Text getInputTexts :: FormInput input => input -> [Text] -- | Get a file descriptor for an uploaded file getInputFile :: (FormInput input, FormError input err) => input -> Either err (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 -- | The core module for ditto. -- -- This module provides the Form type and helper functions for -- constructing typesafe forms inside arbitrary "views" / web frameworks. -- ditto is meant to be a generalized formlet library used to -- write formlet libraries specific to a web / gui framework module Ditto.Core -- | The Form's state is just the range of identifiers so far type FormState m = StateT FormRange m -- | ditto's representation of a formlet -- -- It's reccommended to use ApplicativeDo where possible when -- constructing forms data Form m input err view a Form :: (input -> m (Either err a)) -> m a -> FormState m (View err view, Result err (Proved a)) -> Form m input err view a -- | Decode the value from the input [formDecodeInput] :: Form m input err view a -> input -> m (Either err a) -- | The initial value [formInitialValue] :: Form m input err view a -> m a -- | A FormState which produces a View and a -- Result [formFormlet] :: Form m input err view a -> FormState m (View err view, Result err (Proved a)) -- | The environment typeclass: the interface between ditto and a given -- framework class Monad m => Environment m input | m -> input environment :: Environment m input => FormId -> m (Value input) -- | Run the form, but always return the initial value newtype NoEnvironment input m a NoEnvironment :: m a -> NoEnvironment input m a [getNoEnvironment] :: NoEnvironment input m a -> m a -- | Run the form, but with a given environment function newtype WithEnvironment input m a WithEnvironment :: ReaderT (FormId -> m (Value input)) m a -> WithEnvironment input m a [getWithEnvironment] :: WithEnvironment input m a -> ReaderT (FormId -> m (Value input)) m a -- | environment which will always return the initial value noEnvironment :: Applicative m => FormId -> m (Value input) -- | infix mapView: succinctly mix the view dsl and the formlets -- dsl e.g. div_ [class_ "my cool form"] @$ do (_ :: Form m input err -- view' a). (@$) :: Monad m => (view -> view') -> Form m input err view a -> Form m input err view' a infixr 0 @$ -- | Catch errors purely catchFormError :: Monad m => ([err] -> a) -> Form m input err view a -> Form m input err view a -- | Catch errors inside Form / m catchFormErrorM :: Monad m => Form m input err view a -> ([err] -> Form m input err view a) -> Form m input err view a -- | Evaluate a form -- -- Returns: -- -- eitherForm :: Monad m => Text -> Form m input err view a -> m (Either view a) -- | Get a FormId from the FormState getFormId :: Monad m => FormState m FormId -- | Utility function: Get the current input getFormInput :: Environment m input => FormState m (Value input) -- | Utility function: Gets the input of an arbitrary FormId. getFormInput' :: Environment m input => FormId -> FormState m (Value input) -- | Utility function: Get the current range getFormRange :: Monad m => FormState m FormRange -- | Get a FormIdName from the FormState getNamedFormId :: Monad m => Text -> FormState m FormId -- | Increment a form ID incrementFormId :: FormId -> FormId -- | Check if a FormId is contained in a FormRange isInRange :: FormId -> FormRange -> Bool -- | Map over the Result and View of a form mapResult :: Monad m => (Result err (Proved a) -> Result err (Proved a)) -> (View err view -> View err view) -> Form m input err view a -> Form m input err view a -- | Common operations on Forms -- -- 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 -- | Utility Function: turn a view and pure value into a successful -- FormState mkOk :: Monad m => FormId -> view -> a -> FormState m (View err view, Result err (Proved a)) -- | Select the errors originating from this form or from any of the -- children of this form retainChildErrors :: FormRange -> [(FormRange, e)] -> [e] -- | Select the errors for a certain range retainErrors :: FormRange -> [(FormRange, e)] -> [e] -- | Run a form runForm :: Monad m => Text -> Form m input err view a -> m (View err view, Result err (Proved a)) -- | Run a form, and unwrap the result runForm_ :: Monad m => Text -> Form m input err view a -> m (view, Maybe a) -- | Always succeed decoding successDecode :: Applicative m => a -> input -> m (Either err a) -- | Turns a FormId into a FormRange by incrementing the -- base for the end Id unitRange :: FormId -> FormRange -- | Make a form which renders a view, accepts no input and -- produces no output view :: Monad m => view -> Form m input err view () -- | Run the form with no environment, return only the html. This means -- that the values will always be their defaults viewForm :: Monad m => Text -> Form m input err view a -> m view -- | lift the result of a decoding to a Form pureRes :: (Monad m, Monoid view, FormError input err) => a -> Either err a -> Form m input err view a -- | Form is a MonadTrans, but we can't have an instance -- of it because of the order and kind of its type variables liftForm :: (Monad m, Monoid view) => m a -> Form m input err view a instance GHC.Base.Functor m => GHC.Base.Functor (Ditto.Core.Form m input err view) instance GHC.Base.Applicative m => GHC.Base.Applicative (Ditto.Core.NoEnvironment input m) instance GHC.Base.Functor m => GHC.Base.Functor (Ditto.Core.NoEnvironment input m) instance GHC.Base.Monad m => GHC.Base.Monad (Ditto.Core.NoEnvironment input m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Ditto.Core.WithEnvironment input m) instance GHC.Base.Functor m => GHC.Base.Functor (Ditto.Core.WithEnvironment input m) instance GHC.Base.Monad m => GHC.Base.Monad (Ditto.Core.WithEnvironment input m) instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (Ditto.Types.FormId -> m (Ditto.Types.Value input)) (Ditto.Core.WithEnvironment input m) instance Control.Monad.Trans.Class.MonadTrans (Ditto.Core.WithEnvironment input) instance GHC.Base.Monad m => Ditto.Core.Environment (Ditto.Core.WithEnvironment input m) input instance GHC.Base.Monad m => Ditto.Core.Environment (Ditto.Core.NoEnvironment input m) input instance (Ditto.Core.Environment m input, GHC.Base.Monoid view, Ditto.Backend.FormError input err) => GHC.Base.Monad (Ditto.Core.Form m input err view) instance (GHC.Base.Monad m, GHC.Base.Monoid view, Ditto.Backend.FormError input err, Ditto.Core.Environment m input) => GHC.Base.Alternative (Ditto.Core.Form m input err view) instance (GHC.Base.Monad m, GHC.Base.Monoid view) => GHC.Base.Applicative (Ditto.Core.Form m input err view) 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.Monad m, GHC.Base.Monoid view, GHC.Base.Monoid a) => GHC.Base.Monoid (Ditto.Core.Form m input err view a) instance GHC.Base.Functor m => Data.Bifunctor.Bifunctor (Ditto.Core.Form m input err) -- | 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: data Proof m err a b Proof :: (a -> m (Either err b)) -> (a -> b) -> Proof m err a b -- | function which provides the proof [proofFunction] :: Proof m err a b -> a -> m (Either err b) -- | usually const b [proofNewInitialValue] :: Proof m err a b -> a -> b -- | apply a Proof to a Form prove :: (Monad m, Monoid view, FormError input error) => 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, Monoid view, FormError input error) => Form m input error view a -> (a -> m (Either error b)) -> (a -> b) -> Form m input error view b -- | transform the Form result using an Either function. transformEither :: (Monad m, Monoid view, FormError input error) => Form m input error view a -> (a -> Either error b) -> (a -> 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) -> i -> Proof m error String i -- | read signed decimal number signedDecimal :: (Monad m, Eq i, Real i) => (String -> error) -> i -> Proof m error String i -- | read RealFrac number realFrac :: (Monad m, RealFrac a) => (String -> error) -> a -> Proof m error String a -- | read a signed RealFrac number realFracSigned :: (Monad m, RealFrac a) => (String -> error) -> a -> Proof m error String a instance GHC.Base.Functor m => GHC.Base.Functor (Ditto.Proof.Proof m err a) -- | This module provides helper functions for HTML input elements. These -- helper functions are not specific to any particular web framework or -- html library. -- -- Additionally, the inputs generated with the functions from this module -- will have their names/ids automatically enumerated. -- -- For named formlets, see Ditto.Generalized.Named module Ditto.Generalized.Unnamed -- | a choice for inputChoice data Choice lbl a Choice :: FormId -> lbl -> Bool -> a -> Choice lbl a -- | the formId [choiceFormId] :: Choice lbl a -> FormId -- | label [choiceLabel] :: Choice lbl a -> lbl -- | is the choice selected [choiceIsSelected] :: Choice lbl a -> Bool -- | the haskell value of the choice [choiceVal] :: Choice lbl a -> a -- | used for constructing elements like <input -- type="text">, which pure a single input value. input :: (Environment m input, FormError input err) => (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 :: (Environment m input, FormError input err) => (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 :: Environment m input => (FormId -> view) -> Form m input err view () -- | used for <input type="file"> inputFile :: forall m input err view ft. (Environment m input, FormInput input, FormError input err, ft ~ FileType input, Monoid ft) => (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 input err, FormInput input, Environment m input, Eq a) => [(a, lbl)] -> (input -> Either err [a]) -> (FormId -> [Choice lbl a] -> view) -> (a -> Bool) -> Form m input err view [a] -- | radio buttons, single <select> boxes inputChoice :: forall a m err input lbl view. (FormError input err, FormInput input, Environment m input, Eq a, Monoid view) => (a -> Bool) -> NonEmpty (a, lbl) -> (input -> Either err a) -> (FormId -> [Choice lbl a] -> view) -> Form m input err view a -- | this is necessary in order to basically map over the decoding function inputList :: forall m input err a view. (Monad m, FormError input err, Environment m input) => (input -> m (Either err [a])) -> ([view] -> view) -> [a] -> view -> (a -> Form m input err view a) -> Form m input err view [a] -- | used to create <label> elements label :: Environment m input => (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 :: Environment m input => ([err] -> view) -> Form m input err view () -- | similar to errors but includes err messages from children of -- the form as well. childErrors :: Environment m input => ([err] -> view) -> Form m input err view () -- | modify the view of a form based on its errors withErrors :: Environment m input => (view -> [err] -> view) -> Form m input err view a -> Form m input err view a -- | modify the view of a form based on its child errors withChildErrors :: Monad m => (view -> [err] -> view) -> Form m input err view a -> Form m input err view a -- | This module provides helper functions for HTML input elements. These -- helper functions are not specific to any particular web framework or -- html library. -- -- For unnamed (enumerated) formlets, see -- Ditto.Generalized.Unnamed module Ditto.Generalized.Named -- | a choice for inputChoice data Choice lbl a Choice :: FormId -> lbl -> Bool -> a -> Choice lbl a -- | the formId [choiceFormId] :: Choice lbl a -> FormId -- | label [choiceLabel] :: Choice lbl a -> lbl -- | is the choice selected [choiceIsSelected] :: Choice lbl a -> Bool -- | the haskell value of the choice [choiceVal] :: Choice lbl a -> a -- | used for constructing elements like <input -- type="text">, which pure a single input value. input :: (Environment m input, FormError input err) => Text -> (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 :: (Environment m input, FormError input err) => Text -> (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 :: Environment m input => Text -> (FormId -> view) -> Form m input err view () -- | used for <input type="file"> inputFile :: forall m input err view ft. (Environment m input, FormInput input, FormError input err, ft ~ FileType input, Monoid ft) => Text -> (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 input err, FormInput input, Environment m input, Eq a) => Text -> [(a, lbl)] -> (input -> Either err [a]) -> (FormId -> [Choice lbl a] -> view) -> (a -> Bool) -> Form m input err view [a] -- | radio buttons, single <select> boxes inputChoice :: forall a m err input lbl view. (FormError input err, FormInput input, Environment m input, Eq a, Monoid view) => Text -> (a -> Bool) -> NonEmpty (a, lbl) -> (input -> Either err a) -> (FormId -> [Choice lbl a] -> view) -> Form m input err view a -- | this is necessary in order to basically map over the decoding function inputList :: forall m input err a view. (Monad m, FormError input err, Environment m input) => Text -> (input -> m (Either err [a])) -> ([view] -> view) -> [a] -> view -> (a -> Form m input err view a) -> Form m input err view [a] -- | used to create <label> elements label :: Environment m input => Text -> (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 :: Environment m input => ([err] -> view) -> Form m input err view () -- | similar to errors but includes err messages from children of -- the form as well. childErrors :: Environment m input => ([err] -> view) -> Form m input err view () -- | modify the view of a form based on its errors withErrors :: Environment m input => (view -> [err] -> view) -> Form m input err view a -> Form m input err view a -- | modify the view of a form based on its child errors withChildErrors :: Monad m => (view -> [err] -> view) -> Form m input err view a -> Form m input err view a -- | a Form with no view ireq :: forall m input view err a. (Monoid view, Environment m input, FormError input err) => Text -> (input -> Either err a) -> a -> Form m input err view a -- | an optional Form with no view iopt :: forall m input view err a. (Monoid view, Environment m input, FormError input err) => Text -> (input -> Either err a) -> Maybe a -> Form m input err view (Maybe a) -- | Reexports important modules of ditto module Ditto