-------------------------------------------------------------------------------- {-# LANGUAGE OverloadedStrings #-} -- | Functionality related to index storage and the DefaultList type. module Text.Digestive.Form.List ( indicesRef , parseIndices , unparseIndices , DefaultList (..) , defaultListIndex ) where -------------------------------------------------------------------------------- import Control.Applicative ((<$>), (<*>)) import Data.Foldable (Foldable (..)) import Data.Maybe (mapMaybe) import Data.Text (Text) import qualified Data.Text as T import Data.Traversable (Traversable (..)) import Prelude hiding (foldr) -------------------------------------------------------------------------------- import Text.Digestive.Util -------------------------------------------------------------------------------- -- | Key used to store list indices indicesRef :: Text indicesRef = "indices" -------------------------------------------------------------------------------- -- | Parse a string of comma-delimited integers to a list. -- Unparseable substrings are left out of the result. parseIndices :: Text -> [Int] parseIndices = mapMaybe (readMaybe . T.unpack) . T.split (== ',') -------------------------------------------------------------------------------- -- | Serialize a list of integers as a comma-delimited Text unparseIndices :: [Int] -> Text unparseIndices = T.intercalate "," . map (T.pack . show) -------------------------------------------------------------------------------- -- | A list which, when indexed on non-existant positions, returns a default -- value. data DefaultList a = DefaultList a [a] -------------------------------------------------------------------------------- instance Functor DefaultList where fmap f (DefaultList x xs) = DefaultList (f x) (map f xs) -------------------------------------------------------------------------------- instance Foldable DefaultList where foldr f z (DefaultList x xs) = f x (foldr f z xs) -------------------------------------------------------------------------------- instance Traversable DefaultList where traverse f (DefaultList x xs) = DefaultList <$> f x <*> traverse f xs -------------------------------------------------------------------------------- -- | Safe indexing of a DefaultList - returns the default value if -- the given index is out of bounds. defaultListIndex :: DefaultList a -> Int -> a defaultListIndex (DefaultList x xs) i | i < 0 = x | otherwise = case drop i xs of (y : _) -> y [] -> x