content: --------------------------------------------------------------------------------
  {-# LANGUAGE FlexibleContexts  #-}
  {-# LANGUAGE FlexibleInstances #-}
  {-# LANGUAGE OverloadedStrings #-}
  -- | Core types used internally
  module Text.Digestive.Types
      ( Result (..)
      , resultMapError
      , Path
      , toPath
      , fromPath
      , Method (..)
      , FormInput (..)
      , Env
      ) where
  
  
  --------------------------------------------------------------------------------
  import           Control.Applicative (Applicative (..))
  import           Data.Monoid         (Monoid, mappend)
  
  
  --------------------------------------------------------------------------------
  import           Data.Text           (Text)
  import qualified Data.Text           as T
  
  
  --------------------------------------------------------------------------------
  -- | A mostly internally used type for representing Success/Error, with a
  -- special applicative instance
  data Result v a
      = Success a
      | Error v
      deriving (Show)
  
  
  --------------------------------------------------------------------------------
  instance Functor (Result v) where
      fmap f (Success x) = Success (f x)
      fmap _ (Error x)   = Error x
  
  
  --------------------------------------------------------------------------------
  instance Monoid v => Applicative (Result v) where
      pure x                  = Success x
      Error x   <*> Error y   = Error $ mappend x y
      Error x   <*> Success _ = Error x
      Success _ <*> Error y   = Error y
      Success x <*> Success y = Success (x y)
  
  
  --------------------------------------------------------------------------------
  instance Monoid v => Monad (Result v) where
      return x          = Success x
      (Error x)   >>= _ = Error x
      (Success x) >>= f = f x
  
  
  --------------------------------------------------------------------------------
  -- | Map over the error type of a 'Result'
  resultMapError :: (v -> w) -> Result v a -> Result w a
  resultMapError f (Error x)   = Error (f x)
  resultMapError _ (Success x) = Success x
  
  
  --------------------------------------------------------------------------------
  -- | Describes a path to a subform
  type Path = [Text]
  
  
  --------------------------------------------------------------------------------
  -- | Create a 'Path' from some text
  toPath :: Text -> Path
  toPath = filter (not . T.null) . T.split (== '.')
  
  
  --------------------------------------------------------------------------------
  -- | Serialize a 'Path' to 'Text'
  fromPath :: Path -> Text
  fromPath = T.intercalate "."
  
  
  --------------------------------------------------------------------------------
  -- | The HTTP methods
  data Method = Get | Post
      deriving (Eq, Ord, Show)
  
  
  --------------------------------------------------------------------------------
  -- | The different input types sent by the browser
  data FormInput
      = TextInput Text
      | FileInput FilePath
      deriving (Show)
  
  
  --------------------------------------------------------------------------------
  -- | An environment (e.g. a server) from which we can read input parameters. A
  -- single key might be associated with multiple text values (multi-select).
  type Env m = Path -> m [FormInput]
  